DEV Community

Simone Gentili
Simone Gentili

Posted on

Split makefile and import targets from separate files

Start your makefile

Imagine the beginning of a project where some task are managed with a Makefile. At the beginning of the project maybe your tasks are two or three. Imagine the Makefile of something similar of the following few lines.

install:
    @echo "some install stuff"
build:
    @echo "some build stuff"
Enter fullscreen mode Exit fullscreen mode

Adding features

And then imagine that the project grow and grow also the number of tasks. Some tasks to run tests. Some other to drop, init, create, migrate or add fixtures to the database. And so on ...

install:
    @echo "some stuff"
build:
    @echo "some other stuff"
test:
    @echo "some unit test"
e2e:
    @echo "some end 2 end stuff"
fixtures:
    @echo "fixtures"
init-db:
    @echo "database, ..."
erase:
    @echo "clear cache, containers and other stuffs"
some-docker-task:
    @echo "do something"
some-other-task:
    @echo "leave a comment"
some-other-task:
    @echo "please click on Hear or Unicorn"
Enter fullscreen mode Exit fullscreen mode

I mean, ... your makefile may explode soon if you do nothing to keep it clean and easy to read or try to, .. hay! Can we split makefile? Mmm no, .. isn the right question.

May I import command from other sources?

YES! And the keyword to use is "include". Ok, .. follow me in the rest of the article: Try to split some tasks in different sets. For example you can have these sets of tasks:

  • tests
    • unit
    • e2e
    • functional
  • docker-stuff
    • build
    • up
    • stop

An hypothetical file could be similar to the following:

tests-unit:
    echo @"do something"
test-e2e:
    echo @"do something"
test-functional:
    echo @"do something"
docker-build:
    echo @"do something"
docker-up:
    echo @"do something"
docker-stop:
    echo @"do something"
Enter fullscreen mode Exit fullscreen mode

Ok, this is not so big but imagine tens od sets. You makefile could really contains. Imagine hundred of lines of makefile. I am sure the reading could not be so easy.

Split one Makefile

Now imagine two file: test.file and docker.file.

docker.file may contain

docker-build:
    echo @"do something"
docker-up:
    echo @"do something"
docker-stop:
    echo @"do something"
Enter fullscreen mode Exit fullscreen mode

and test.file may contain

tests-unit:
    echo @"do something"
test-e2e:
    echo @"do something"
test-functional:
    echo @"do something"
Enter fullscreen mode Exit fullscreen mode

And imagine to include them inside the main Makefile:

include test.file docker.file
Enter fullscreen mode Exit fullscreen mode

Now you can run simply make test-unit and it works. But

Autocompletion lost

Whenever all targets are inside the Makefile autocompletion works. Moving targets outside, it stop working. Is not a Makefile issue but is an autocompletion issue. I am using oh-my-zsh. Maybe I need some plugin. I do not know. Did you know how to fix this?

Fix autocompletion

I've found a little trick to fix autocompletion. I've updated my Makefile with new target that call targets inside imported files. This works!!! Now make<tab> shows also unit-test.

include test.file docker.file

unit-test: test-unit
Enter fullscreen mode Exit fullscreen mode

Conclusion

Keep makefile ordered and clean is good. But is not so good lost autocompletion. If you know all the targets is ok. But without autocompletion, for a new teammate could be hard to find the right command inside included file. But, ... this is fixable. So, ... I am simply happy to this nice feature of makefiles.

Top comments (0)