|
|
|
|
|
by nrclark
765 days ago
|
|
> What does a makefile look like for "install this list of dependencies with pip/homebrew/apt, and don't run it twice?" It looks like this: default: your_task
VENV_DIR := venv
$(VENV_DIR)/bin/python: requirements.txt
python -m venv $(VENV_DIR)
. $(VENV_DIR)/bin/activate && pip install -r requirements.txt
your_task: $(VENV_DIR)/bin/python
do_your_thing
clean:
rm -rf $(VENV_DIR)
> C and C++ compilers at this stage are the only places that I work with file based dependencies. Unless you explicitly declare all the headers as dependencies in a makefile, make won't rebuild a cpp file if you change a header. IME ninja (plus cmake to generate it) has entirely superseded make in this space. Tools and languages comes with it's own build tool (see above - go/cargo/dotnet/etc) or state tracking (docker) that break make's assumption of file based dependencies.In our Python example above, you have a file-based dependency between requirements.txt and your virtual environment. And then you have a file-based dependency on your virtual-environment's Python for whatever task you're trying to run. > Because every make file I've ever used in recent memory has been 30% workarounds to avoid file based dependencies, and work around subtle footguns that make has, rather than actually doing what I want it to do - execute a build command. Why would you want to avoid expressing your dependencies? File dependencies exist, and are the simplest / most correct model for 75% of all build automation. When somebody has to sit down and read your Makefile, isn't it nice to have a way to express "these are the files that actually matter for task X"? |
|