2
votes

I am trying to compile my project which has the following structure

Project:

  • MakeFile
  • Executable
  • Source1
    • .cxx
    • .h
  • Source2
    • .cxx
    • .h
  • Build
    • *.o

And I'm having difficulty writting a Makefile to compile. I currently have commands like:

Src1 = $(wildcard $(SRCDIR1)/*.cxx)
Obj1 = $(patsubst $(SRCDIR1)/%.cxx, $(OBJDIR)/%.o, $(Src1))

But then I have difficulty making the compile rules for the object files a) Because I can no longer do:

$(Obj1): %.cxx
    $(CXX) $(CFLAGS) -c $(@:.o=.cxx) -o $@

Because the '$@' command now includes the path of the build directory and b) because the prerequisites now include the build path and I should have a source path. I have read large bits of the make manual to try and find a solution but no luck. Any help towards a solution appreciated! Jack

2
Thanks Maxim, thats a great answer. However, the main difficulty I am having is building all the object codes to the BUILD directory when they exist in the SRC directory. Jack - JMzance

2 Answers

0
votes

From personal experience, after playing around a bit with "raw" Makefiles, I'd really recommend using some tool building the Makefiles for you, like automake or cmake.

You'll still have to specify all the source files manually - but at least I prefer that to manually fiddling around with the Makefiles.

0
votes

One option I prefer is building an isomorphic directory structure in the build directory. That is, a source file ${src_dir}/project_x/main.cxx builds into ${build_dir}/project_x/main.o. This way you are protected from name clashes when there are source files with the same name in different source directories. The compiler rule would look something like:

${obj_dir}/%.o : ${src_dir}/%.cxx # % includes directory name, e.g. project_x/main
    @-mkdir -p ${@D}
    ${CXX} -c -o $@ ${CPPFLAGS} ${CXXFLAGS} $<

Notice how in the above it creates the target directory on the fly. This is a bit simplistic, in a real-world build system object files depend (using order-only dependency) on its directory, so that make automatically creates the destination directory if it does not exist instead of speculatively trying to create them for each target object file even if it already exists.