3 ms·
The article reads I think an important thing to know about make(1) is that you don't need to write a Makefile to use it. There are default rules for C, C++
by bigdict 3y ago
The article reads
I think an important thing to know about make(1) is that you don't need to write a Makefile to use it. There are default rules for C, C++ and probably Fortran.
And then it goes against its own spirit... You don't need this:
OBJS = foo.o bar.o baz.o
foo: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
Just do:
foo: foo.o bar.o baz.o
It respects LDFLAGS and LDLIBS.
- Brian_K_White 3y agoLists of files are usually used more than once for more than one task. This would only make sense if the only rule that needed the list was that one that builds, no install/uninstall/package/modify/audit/hash/clean/etc, which is never the case. You also don't want to use globbing in place of an explicit list either.
- bigdict 3y agoSure, I'm just pointing out you don't need to type out the C compiler invocation again. FOOOBJS = foo.o bar.o baz.o foo: $(FOOOBJS)
- Brian_K_White 3y agoAh got it. Agreed.
- e12e 3y agoSo: > The example Makefile in its entirety: CFLAGS += -Wall -Wextra LDLIBS = -lcurses OBJS = foo.o bar.o baz.o foo: $(OBJS) $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ foo.o bar.o: foo.h clean: rm -f $(OBJS) foo Become: CFLAGS += -Wall -Wextra LDLIBS = -lcurses OBJS = foo.o bar.o baz.o ? foo: $(OBJS) foo.o bar.o: foo.h clean: rm -f $(OBJS) foo
- Karellen 3y agoBut the OBJS allows for an easy `clean` target, defined further down the article. Personally, I'd have gone with foo: $(OBJS) $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS) to put all flag options first, then the output option, then using `$<` for the compiler inputs, and additional linker inputs last. But that is somewhat idiosyncratic, and based on some half-remembered ideas of second-hand stories of how compilers used to process their command parameters back in the '90s (and before). Those ideas probably aren't relevant now (and may not have been entirely correct originally), so if the recipe in the original article works for the author, I'm not going to say they're "wrong" for doing it the way they did.
- adrian_b 3y agoYou do not need to write any project-specific definition for OBJS. You can include in the project Makefile a generic Makefile that may contain a definition like: OBJS := $(CPP_FILES:.cpp=.o) $(CXX_FILES:.cxx=.o) $(CC_FILES:.cc=.o) \ $(C_FILES:.c=.o) $(SS_FILES:.S=.o) $(S_FILES:.s=.o) $(F_FILES:.f=.o) \ $(L_FILES:.l=.o) $(Y_FILES:.y=.o) $(RC_FILES:.rc=.o) $(O_FILES) which builds an OBJS list from all the lists of source files that "make" has previously gathered from all the directories with source files that belong to the project. The automatically defined OBJS can be used for linking, and a similar list without $(O_FILES), i.e. without .o files that are source files, not intermediate files, can be used for cleaning.
- matheusmoreira 3y agoThis is simple enough if you're okay with intermediary files littering the entire codebase. Targets and their intermediary files will be written right next to their sources and the whole tree will be a huge mess. The makefile quickly gets complicated if one wants an organized source tree such as: source/module/file1.c source/module/file2.c source/main.c source/tools/tool.c To be transformed into an architecture specific build tree whose organization automatically matches that of the source tree: build/$arch/prerequisites/module/file1.d build/$arch/prerequisites/module/file2.d build/$arch/prerequisites/main.d build/$arch/prerequisites/tools/tool.d build/$arch/objects/module/file1.o build/$arch/objects/module/file2.o build/$arch/objects/main.o build/$arch/objects/tools/tool.o build/$arch/executables/main build/$arch/executables/tool The general solution to that is the explicit path method: https://make.mad-scientist.net/papers/multi-architecture-builds/#explicitpath https://make.mad-scientist.net/papers/multi-architecture-bui...