gnu make - Makefile to support 2 executables -
i trying update makefile support building binary of project, , binary of unit tests.
my directory structure following
|-code/ |--|--src/ |--|--inc/ | |-tests/ |--|--src/ |--|--inc/
my makefile compiles binary code well, having issues test. test folder contains unit test tests classes in code/src/. have file main.cpp in code/src/ contains main() function, , file, called test.cpp in tests/src contains own main() function.
this led me complicated makefile:
cc = g++ flags = -g -c -wall includedir = -icode/inc -itests/inc builddir = build sourcedir = code/src sources = $(wildcard $(addsuffix /*.cpp,$(sourcedir))) temp_obj = $(sources:%.cpp=%.o) not_dir = $(notdir $(temp_obj)) objects = $(addprefix $(builddir)/, $(not_dir)) test_dir = tests/src test_sources = $(wildcard $(addsuffix /*.cpp,$(test_dir))) test_temp_obj = $(test_sources:%.cpp=%.o) test_not_dir = $(notdir $(test_temp_obj)) test_objects = $(addprefix $(builddir)/, $(test_not_dir)) executable = client test_executable = testunit all: $(builddir) $(builddir)/$(executable) $(builddir)/$(test_executable) $(builddir): mkdir -p $@ $(builddir)/$(executable): $(objects) $(cc) $^ -o $@ $(builddir)/%.o : code/src/%.cpp $(cc) $(flags) $< $(includedir) -o $@ $(builddir)/$(test_executable): $(objects) $(test_objects) @rm -f $(builddir)/main.o $(cc) $^ -o $@ $(builddir)/%.o : tests/src/%.cpp $(cc) $(flags) $< $(includedir) -o $@ clean: rm -rf $(builddir)
it fails error:
g++: error: build/main.o: no such file or directory make: *** [build/testunit] error 1
which because have line:
@rm -f $(builddir)/main.o
but otherwise error (there main in main.cpp , test.cpp in code/src/ , tests/code/ respectively):
/tests/src/test.cpp:7: multiple definition of `main' code/src/main.cpp:6: first defined here collect2: error: ld returned 1 exit status
there lot of duplication in makefile, , love more succinct achieves purpose of building 2 binaries 2 folders, although code shared.
any please appreciated. thank much!
there number of problems makefile.
first, there no rule build test object files, such test.o
. rule building objects requires source in code/src/
; don't know how far enough see linker error.
let's change object rule static pattern rule:
$(objects) : $(builddir)/%.o : code/src/%.cpp $(cc) $(flags) $< $(includedir) -o $@
then can add additional rule test objects:
$(test_objects) : $(builddir)/%.o : tests/src/%.cpp $(cc) $(flags) $< $(includedir) -o $@
(never mind redundancy now-- have working first.)
now should see linker error in rule:
$(builddir)/$(test_executable): $(objects) $(test_objects) ...
in list of prerequisites 2 files, main.o
, test.o
fighting on gets define main()
. want test.o
, main.o
must go:
$(builddir)/$(test_executable): $(filter-out build/main.o,$(objects)) $(test_objects) ...
try , tell result. once it's working can slim down.
Comments
Post a Comment