LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Makefiles, building source from another folder with obj files > subfolder of current? (https://www.linuxquestions.org/questions/programming-9/makefiles-building-source-from-another-folder-with-obj-files-subfolder-of-current-912974/)

Funkster 11-11-2011 04:04 AM

Makefiles, building source from another folder with obj files > subfolder of current?
 
Hi all,

I've been stuck on this one for a while now so really hoping someone can help! I have an array of folders of C/C++ source that are common code to several projects, and some more folders (by the side of the others) that contain projects themselves.

When I build a project, I want to be able to include a sources.mk from an external folder, and have the objects for those included sources go into a subfolder of the project directory so as not to clutter the common folder up with project-specific objects (each project can have different flags, optimisations etc.)

As an example, here's a folder structure:

source/common.mk

source/common/stuff/aaa.c
source/common/stuff/sources.mk

source/projects/thing/main.c
source/projects/thing/Makefile

The Makefile in projects/thing will include common/stuff/sources.mk to get a list of the sources in that folder (appended to the list of sources already in Makefile). Sources in sources.mk are prepended with the relative path between Makefile and sources.mk as follows:

Code:

THIS_TOP := $(dir $(lastword $(MAKEFILE_LIST)))
SOURCES_C += $(THIS_TOP)/aaa.c

I want all objects to go into (dir I'm building in)/objdir/, preferably with subfolders based on the path from source so e.g.:

cd projects/thing; make
creates:
projects/thing/objdir/main.o
projects/thing/objdir/common/stuff/aaa.o

I make a list of object files and strip the ../ out of the relative path as follows:

Code:

__OBJECTS=$(SOURCES_C:.c=.o) $(SOURCES_CPP:.cpp=.o)
_OBJECTS = $(subst ../,,$(__OBJECTS))
OBJECTS = $(patsubst %,$(OBJDIR)/%,$(_OBJECTS))

The problem I have is that I can't seem to come up with a rule (to go in common.mk) to make this local .o from a remote .c! I've tried a second expansion to try to make a rule that searches in the list of .c files for the one that corresponds to the .o that is required, but can't make that work due to the lack of multiple wildcards in filter...

Code:

.SECOND_EXPANSION:
$(OBJDIR)/%.o: $$(filter %$$(addsuffix .c,$$(subst .o,,$$(notdir $$@))),$$(SOURCES_C)) | $(OBJDIR)/ $(OBJSUBDIRS)/
        $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

I'm really tearing my hair out on this one... has anyone managed something similar? If all else fails I'll just build them as static libraries (already have libraries building in subdir of project folder like I want) but since that creates extra makefiles to maintain I'd really like to avoid it.

Any help greatly appreciated!

Thanks,
--
Olly

dwhitney67 11-11-2011 06:29 AM

I use something similar to the following when I develop C++ projects:
Code:

OBJDIR  = .srcobjs

SRCS    := $(shell find . -name '*.cpp')
SRCDIRS := $(shell find . -name '*.cpp' -exec dirname {} \; | uniq)
OBJS    := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SRCS))
DEPS    := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SRCS))

DEBUG    = -g
INCLUDES = -I./Include
CXXFLAGS = $(DEBUG) -Wall -pedantic $(INCLUDES) -c

DEPENDS  = -MT $@ -MD -MP -MF $(subst .o,.d,$@)

To compile the code:
Code:

$(OBJDIR)/%.o: %.cpp
        $(CXX) $(CXXFLAGS) $(DEPENDS) $< -o $@

Now, as far as working with C and C++ on a single project, I have never done this. It would seem to me that if you have independent C source code, that you should build a static- or shared-library. Then your C++ code would be linked with this library.


All times are GMT -5. The time now is 10:16 PM.