18 ms·
No need to explicitly declare dependencies, you have wildcards and macros at hand to manage redundancy (1). If the compiler/program accepts a file and produces
by gkya 10y ago
No need to explicitly declare dependencies, you have wildcards and macros at hand to manage redundancy (1). If the compiler/program accepts a file and produces another, it can be used just as easily as the C compiler. My website uses awk, m4 and html-tidy on a pipeline to produce HTML, and with 45 lines of make (with about 10-15% whitespace) I build everything, with html-tidy being optional.
- amelius 10y agoBut some languages allow an "#include / import" construct. You'll have to somehow walk all those dependencies and convert them into something Make understands.
- coldtea 10y agoWhy would that be the responsibility of Make? Of course you need to convert those externally -- with e.g. the C preprocessor for C files...
- amelius 10y agoWell, Make could figure them out, for example by using the Linux ptrace syscall, or by using libfuse. However, my biggest problem with Make is still that it does not allow for dependencies in the form of variables.
- LukeShu 10y agoWhat do you mean by "dependencies in the form of variables"?
- wbl 10y agoLet's say I need to build the library again with a different set of options. Make clean and rebuild is only solution, even if not needed.
- khedoros 10y agoYou could also output to different directories, depending on the values of variables, like for separate debug and release builds. Of course, this is a work-around for variable dependencies. You'd have to change the filename somehow for every variable that you want to track.
- munificent 10y agoWhat I do is split the makefile in two. There's a top level makefile with targets like "make debug" and "make release". Those invoke a secondary makefile that actually builds things and takes options on the command line. That way I can build different configurations to different directories without having to copy/paste all of the rules for each configuration of each file. For example, the main makefile for Wren[1] has rules like: debug: @ $(MAKE) -f util/wren.mk MODE=debug That util/wren.mk [2] then uses "MODE" and a few other options, like: # Mode configuration. ifeq ($(MODE),debug) WREN := wrend C_OPTIONS += -O0 -DDEBUG -g BUILD_DIR := $(BUILD_DIR)/debug else WREN += wren C_OPTIONS += -O3 BUILD_DIR := $(BUILD_DIR)/release endif It has the real rules for compiling files: # VM object files. $(BUILD_DIR)/vm/%.o: src/vm/%.c $(VM_HEADERS) @ printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)" @ mkdir -p $(BUILD_DIR)/vm @ $(CC) -c $(CFLAGS) -Isrc/include -Isrc/optional -Isrc/vm -o $@ $(FILE_FLAG) $< Took me a while to come up with this and quite some time to get it working, but I've been pretty happy with it so far. [1]: https://github.com/munificent/wren/blob/master/Makefile https://github.com/munificent/wren/blob/master/Makefile [2]: https://github.com/munificent/wren/blob/master/util/wren.mk https://github.com/munificent/wren/blob/master/util/wren.mk
- JdeBP 10y agoAt this point in the chain of thinking, you should read http://cr.yp.to/redo/honest-script.html http://cr.yp.to/redo/honest-script.html
- LukeShu 10y agoHow I handle that: .var.%: FORCE @printf '%s' '$(subst ','\'',$($*))' | sed 's|^|#|' | $(WRITE_IFCHANGED) $@ -include $(wildcard .var*) .PHONY: FORCE Where WRITE_IFCHANGED is a program that essentially does 'cat > $1', but only if doing so would create or change the file. https://lukeshu.com/git/autothing/tree/build-aux/write-ifchanged?h=mod-write-ifchanged https://lukeshu.com/git/autothing/tree/build-aux/write-ifcha... Then, if a file depends on the value of a variable, I have it depend on .var.VARNAME. Of course, that means you may have to do something like $(filter-out .var.%,$^) in the command to generate a file.
- gkya 10y agoA rule can depend on imported files and exclude them with a modification to the variable for rule dependencies: a.o: a.c a.h cc -o ${.TARGET} ${.ALLSRC:M*.c} This is bmake though, I don't know the posix way because I always confuse $*, $>, $+ etc. There is also mkdep(1), tho I didn't ever use it.