2

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

JMzance
  • 1,704
  • 4
  • 30
  • 49

2 Answers2

0

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.

codeling
  • 11,056
  • 4
  • 42
  • 71
0

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.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 1
    FYI, you should normally never have a target depend on a directory. If you really want to do this use make the directory an order-only prerequisite not a normal prerequisite (note this is a GNU make-only feature). – MadScientist Aug 14 '13 at 12:46
  • 1
    @MadScientist Adding/removing a file in a directory updates directory's timestamp, whereas we only care if it exists. So, as you correctly noted, order-only dependencies should be used for directories. – Maxim Egorushkin Aug 14 '13 at 12:54
  • Ok this is definitely helping, most of my files arenow happy to make with the command ${obj_dir}/%.o : ${src_dir}/%.cxx. The problem now is that I also have files which want to end up as ${obj_dir}/%.o files but arent in src_dir, they are in a seperate src directory. Moreover I have a few fortran files which also need compiling and the ${obj_dir}/%.o : ${src_dir}/%.cxx rule does not cover them? – JMzance Aug 14 '13 at 12:59
  • @JackMedley If you have source files in directories outside `${src_dir}` you can either symlink those dirs under `${src_dir}` or add another rule `${obj_dir}/%.o : ${another_src_dir}/%.cxx` – Maxim Egorushkin Aug 14 '13 at 13:04