Create file with source subdirectories

My last project is in C ++ and I am using GNU Make. The layout of the project directory is as follows:

project |-src |-subdir1 |-subdir2 (containing tests) |-doc |-bin 

I would like to be able to call make in the top-level directory (that is, I need a makefile in the project directory) to compile all sources in both "src" subdirectories and place the resulting binary files in the "bin" directory,

What would be the best approach for this? It would also be great if I didn't have to add a make rule for each source file, but just had one for all .cc and .h files in directories.

+8
makefile
source share
3 answers

Make allows you to generalize your rules, so you do not need to create them for each file.

 project |-src |-subdir1 |-subdir2 (containing tests) |-doc |-bin 

You can try something like this:

 #This finds all your cc files and places then into SRC. It equivalent would be # SRC = src/main.cc src/folder1/func1.cc src/folder1/func2.cc src/folder2/func3.cc SRC = $(shell find . -name *.cc) #This tells Make that somewhere below, you are going to convert all your source into #objects, so this is like: # OBJ = src/main.o src/folder1/func1.o src/folder1/func2.o src/folder2/func3.o OBJ = $(SRC:%.cc=%.o) #Tells make your binary is called artifact_name_here and it should be in bin/ BIN = bin/artifact_name_here # all is the target (you would run make all from the command line). 'all' is dependent # on $(BIN) all: $(BIN) #$(BIN) is dependent on objects $(BIN): $(OBJ) g++ <link options etc> #each object file is dependent on its source file, and whenever make needs to create # an object file, to follow this rule: %.o: %.cc g++ -c $< -o $@ 
+14
source share

Use one make-up to complete the build (I'm not a fan of recursive creation). Do not use $(shell) as it kills performance. Place assembly products in a temporary directory.

Sketch:

 subdir1-srcs := $(addprefix subdir1/,1.cc 2.cc 3.cc) subdir1-objs := ${subdir1-srcs:subdir1/%.cc=subdir1/obj/%.o) bin/prog1: ${subdir1-objs} ; gcc $^ -o $@ ${subdir1-objs}: subdir1/obj/%.o: subdir1/%.cc # Static pattern rules rule gcc -c $< -o $@ ${subdir1-objs}: subdir1/obj/.mkdir # Need to create folder before compiling subdir1/obj/.mkdir: mkdir -p ${@D} touch $@ 

Do you see a boiler plate here? Several functions along with $(eval) should allow you to write:

 $(call build,bin/prog1,subdir1,1.cc 2.cc 3.cc) $(call build,bin/prog2,subdir2,a.cc b.cc c.cc d.cc) 

for these purposes, they are automatically added as dependencies of the fake all and beautifully -j compatible ones (just enter make -j5 all to build).

+3
source share

You will need to make a sub-makefile in the directories and use the commands to output the g ++ compiled files to the directories you need. (Use makefile variables, etc.)

You will find a good introduction to recursive makefiles here.

Makefile allows you to use some general rules, for example:

 %.o:%.cpp gcc blahblahblah 

and also you can enable global makefile from another using include .

If you also create a google file, you will find many practical recommendations on this.

-one
source share

All Articles