Search code examples
buildmakefilecmakebuild-system

Which build system will do this the most 'naturally'?


Instead of the flat structure my code currently has, I want to organize it into modules contained in sub-folders (and perhaps sub-sub folders if the modules get big enough).

Each module will have one or more translation units which will each produce a .o file. The final target would be to mash up all these object files into a static library (for now).

I am using plain 'make' and it is already complicated enough.
Is there a system in which the specified model comes naturally or with much less effort compared to writing makefiles by hand ? (If you are going to recommend cmake, I need some hints as I have already tried and could not come up with a good solution.)


Solution

  • Some paraphrased bits from my current project's makefile that may help you out with good old fashioned GNU make:

    SOURCEDIR := dir1 dir2/subdir1 dir3 dir4 dir5/subdir1 dir6/subdir1
    SOURCES := $(foreach srcdir,$(SOURCEDIR),$(wildcard $(srcdir)/*.c))
    OBJECTS := $(patsubst %.c,build/%.o,$(SOURCES))
    OBJDIRS := $(addprefix build/,$(SOURCEDIR))
    MAKEDEPS := $(patsubst %.c,build/%.d,$(SOURCES))
    
    all: example
    
    $(OBJDIRS):
        -mkdir -p $@
    
    build: $(OBJDIRS)
    
    build/%.o : %.c | build
        cc -MMD -c -o $@ $<
    
    example: $(OBJECTS)
        cc -o $@ $(OBJECTS)
    
    -include $(MAKEDEPS)
    

    In essence, it builds all of the source files found in the designated directories into object files located in subdirectories of the build directory in a hierarchy that parallels their source directory layout (important if multiple source files have the same name) and then links the results into an executable example.

    As a bonus, dynamic dependency generation and inclusion via the MAKEDEPS variable and clang's -MMD flag.