Shane P Kelly
Shane P Kelly

Reputation: 221

How to link objects in different directories in c++ with make without refering to them in the makefile?

I'm trying to clean up my project a little and I want to put object files and include files in a separate folder and be able to compile another makefile in my a different testing subdirectory. I would like to do this so that the make file in the testing directory doesn't have to know about the objects in the the above directory: I have been struggling all day trying to figure out make and compilation.

Not sure what I'm doing wrong but in addition to this question I would be appreciative of any information to straighten out my thinking about make and g++ so in the future I know where to look.

Anyways I have 2 Questions both with regards to my project layout:

Project

inc/
--  header files
-obj/
--object files
-source
-make file for project that compiles objects in obj directory (makefile0)
-testing/
--test1/
---test.cc
---makefile1

Question 1

So I want to include the header files in the inc directory in test.cc and then just focus on compiling test.cc like I would if I included a standard library header file. Right now I need to make reference to the object in ../../obj/ in makefile1 and would like to ignore that. and just do something simple like

g++ -I ../../inc/ -c test.cc

How is it possible to do this?

Question 2

In makefile0, for each source file I have to append a $(OBJ) or $(INC) to the front of any file I have in those folders and wondering if there is anyway to clean up my make file an do something like

Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc Utils.o Dispersion.h

instead of

$(ODIR)/Spinless2DFieldIndex.o: Spinless2DFieldIndex.cc $(ODIR)/Utils.o $(INC)/Dispersion.h

Upvotes: 2

Views: 1839

Answers (1)

user657267
user657267

Reputation: 21040

The following should work:

Project/Makefile

objdir := obj/
vpath %.cc source
vpath %.o $(objdir)

CPPFLAGS := -Iinc -MMD -MP

.PHONY: all

all: testing/test1/test

include source/Makefile
include testing/test1/Makefile

Project/source/Makefile

override objects := $(objdir)obj.o

$(objects): $(objdir)%.o: %.cc
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<

clean:: ; $(RM) $(objects) $(objects:.o=.d)

-include $(objects:.o=.d)

Project/testing/test1/Makefile

override dir := $(dir $(lastword $(MAKEFILE_LIST)))
$(dir)test: obj.o

clean:: ; $(RM) $(dir)test $(dir)test.d

-include $(dir)test.d

This should allow for a certain amount of modularity, although the asymmetry in the makefiles betrays the fact that your idea of having a separate obj directory while at the same time wanting to have the test executables in their own directory is perhaps not the best way to organize things. Personally I use a more configure style of makefile that recreates the project tree in the current working directory which helps separate the source from the build.

Upvotes: 3

Related Questions