I'm trying to build my project from the top directory which have the subdirectories
root
Makefile
| common/
| lib/
| app1/
| app2/
| app3/
Assumption 1: I'm at the root directory
Assumption 2: Each subdirectory has its own Makefile
Assumption 3: root's Makefile doesn't actually give any output, it only wants to execute Makefiles in the subdirectories
Assumption 4: common/ and lib/ will contain library files lib1.a and lib2.a
Now, by running make at the root, I want to first build the two libraries lib1.a and lib2.a. And then I want to build the respective apps in app1/, app2/, and app3/. The 3 apps should be linked to lib1.a and lib2.a.
I'm at the stage where I want to first build the two libraries by calling their Makefiles respectively. Here's what I have so far.
CFLAGS = -Wall -pedantic -std=c11 -ggdb
CC = gcc
MAKE = make
LIBPATH = lib/
COMMONPATH = common/
$(LIBPATH)lib1.a : $(LIBPATH)lib1.a # i know this isn't appropriate but it executes make
$(MAKE) -C $(LIBPATH)
$(COMMONPATH)lib2.a : $(COMMONPATH)lib2.a
$(MAKE) -C $(COMMONPATH)
I know there are probably better ways to write this, but the main problem for me is that this makefile only executes whatever is first. Now it will recursveily run the lib1.a's makefile but not for lib2.a. As I want to write similar lines for app1 app2 and app3 I want to resolve this.
Thanks in advance!
You need to declare the dependencies of your applications in your targets.
If app1, app2 and app3 are depends on lib1.a and lib2.a you need to write these dependencies in your target as well . The same for your libraries ( just in case that there are any dependencies existing between both libs as well ).
For instance:
LIBS = lib1.a lib2.a
SRC = app1.cc
app1: $(SRC) $(LIBS) # you will say app1 depends on its source and the libs
# compile your app
Related
A project that I am working on deals with multiple architectures. The code is divided into architecture specific and general modules (which can be shared between the architectures).
I am planning to organize the code as below
TOP
|
|---- Makefile
|
|---- src (arch independent)
|---- inc (arch independent)
|
|----arch1 (arch specific)
|---- src
|---- inc
|---- Makefile
|----arch2 (arch specific)
|---- src
|---- src
|---- Makefile
The arch specific project would be compiled by the Makefile within the arch directory. This makefile includes the Makefile at the TOP level.
The idea was that in the arch specific makefile will have all the src code from within the arch directory and the top level Makefile defines a variable which is simply the path of the TOP level directory, so that the arch specific Makefile can include code from the src folder in the top level.
However, when including the top level Makefile, the defined path variable (through shell pwd command) is evaluuated at the arch specific directory level.
How can I solve this? Is their a better way of doing this?
Right now it's a 2 level structure. But in future I plan top make it multi level with innermost level being arch specific and the layers become more and more general as one moves out to the top level.
What is your top-level makefile doing? - I mean, can you run make on it standalone? If not then all you really appear to gain from it is the list of source files and header locations - it would be easier to just specify those in a common_make.mk or somthing which only contains:
SOURCES += ../src/test1.c
SOURCES += ../src/test2.c
SOURCES += ../src/test3.c
INC += ../inc
then both of your lower level file include this very basic makefile "snippet" and you don't have to worry about the paths.
Usually I am putting common elements into separate config controlled repos and I have my projects the other way around:
arch1/
|--src
|--inc
|--common (repo)
|--inc
|--src
arch2/
|--src
|--inc
|--common (repo)
|--inc
|--src
So here I have two separate repo's with a shared sub-repo. If you wanted to tie the two archx projects together you can add those to into a super-repo with it's own makefile that just does:
make -C arch1
make -C arch2
I see two options for you
Common makefile template for archX/ directories
# ./Makefile.template
ARCH_DIR := $(PWD)
TOP_DIR := $(ARCH_DIR)/..
BUILD_DIR := $(TOP_DIR)/build
# non-architecture specific source code
NOARCH_SRC_DIR := $(TOP_DIR)/src
NOARCH_INC_DIR := $(TOP_DIR)/inc
# non-architecture specific source code
ARCH_SRC_DIR := $(ARCH_DIR)/src
ARCH_INC_DIR := $(ARCH_DIR)/inc
# other stuff...
CFLAGS := -I$(ARCH_INC_DIR) -I$(NOARCH_INC_DIR)
# directory specific variables, e.g. XXX_SRCS
include $(NOARCH_SRC_DIR)/Makefile.include
include $(ARCH_SRC_DIR)/Makefile.include
# generate object file lists
NOARCH_OBJS := $(NOARCH_SRCS:%.c=$(BUILD_DIR)/%.o)
ARCH_OBJS := $(ARCH_SRCS:%.c=$(BUILD_DIR)/%.o)
# add paths to source files
NOARCH_SRCS := $(addprefix $(NOARCH_SRC_DIR)/, $(NOARCH_SRC_DIR))
ARCH_SRCS := $(addprefix $(ARCH_SRC_DIR)/, $(ARCH_SRC_DIR))
# target-specific pattern rules for C files
$(NOARCH_OBJS): %.o: $(NOARCH_SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -o $# -c $<
$(ARCH_OBJS): %.o: $(ARCH_SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -o $# -c $<
... and so ...
ArchX/ directory makefile
# archX/Makefile
# common stuff
include $(PWD)/../Makefile.template
# arch specific targets follow here...
Now you can already run the build using
$ make -C arch1
Top-level directory Makefile
# ./Makefile
ifndef ARCH
$(error you must specifiy ARCH=)
endif
# forward all targets to arch directory
%:
$(MAKE) -C $(ARCH) $(MAKECMDGOAL)
Now you can run the build using
$ make ARCH=arch1
Personally I would not write the top-level makefile at all and use only the former approach.
IMHO you should avoid things like $(shell). But maybe that is just my personal view, take it with a grain of salt...
I have a project directory structure of:
Root
Source
Common
MyFolder
++ My 3 source files and header
When I am building my project it generates 3 to 4 shared libraries. Lib1 compiled using c++98 and others using c++11. Flags are added in CmakeList.txt which is at root.
I need my 3 source files to be compiled for Lib1 and for other Libs as as well. but here what happens is compiler is first compiling my source file for lib using c++11 and then it is trying to use same .o file for Lib1 as well. So for .o file which is generated using c++11 is throwing exception when same is used for c++98 compiled library.
So how do write this in CmakeList.txt such that compiler rather than trying to use same .o file will compile source file again for Lib1(c++98 compiled library)
Is there any flag I can specify so that it won't take precompiled .o file and will compile it again ?
Here flags are not being overridden for different shared libraries but actually same object file by make file is being used for different flags
This is sort of counter to how makefiles and cmake usually work.
Most users consider it really important that make performs an incremental build.
The usual way with makefiles is to do make clean which is supposed to remove any binaries and object files that were created.
However, sometimes I write cmake scripts that use globbing over the source directory to assemble the project. (That means, it says "just grab all *.cpp files in the /src folder and make an executable from them".) A makefile cannot check what files in a directory, so the make build will be broken after I add a new file, and make clean won't fix it -- the whole makefile will need to be regenerated by cmake.
Usually what I do is, I write a simple bash script, named rebuild.sh or something,
#!/bin/bash
rm -rf build
mkdir build
cd build
cmake ..
make -j3
./tests
And I put that in the root of my repository, and add /build to my .gitignore. I call that when I want to do a full rebuild -- it nukes the build directory, so its foolproof. When I want an incremental rebuild, I just type make again in the /build directory.
The rebuild.sh script can also serve a double purpose if you use travis-ci for continuous integration.
Most build system assume the compiled objects remain the same within the same pass. To avoid shooting your foot I would suggest telling the build system they were actually different objects, while still compiled from same source files.
I'm not familiar with cmake but this is how you do with make:
For example you have a a.cpp which you want to compile 2 times for different compiler options:
#include <stdio.h>
int main(int argc, char* argv[]) {
printf ("Hello %d\n", TOKEN);
return 0;
}
And the Makefile would looks like:
SRC := $(wildcard *.cpp)
OBJ_1 := $(patsubst %.cpp,%_1.o,$(SRC))
OBJ_2 := $(patsubst %.cpp,%_2.o,$(SRC))
all: pass1 pass2
pass1: $(OBJ_1)
gcc -o $# $(OBJ_1) -lstdc++
pass2: $(OBJ_2)
gcc -o $# $(OBJ_2) -lstdc++
%_1.o: %.cpp
gcc -DTOKEN=1 -c $< -o $#
%_2.o: %.cpp
gcc -DTOKEN=2 -c $< -o $#
clean:
rm -f $(OBJ_1) $(OBJ_2)
What I do here is generate two different list of object from the same source files, which you can even do the same for dependency(-MMD -MP flags).
I am developing in XCode on Mac OS X El Capitan 10.11.4. My project mixes C, C++11 and Embedded Python.
My project works as I can invoke a Python script and return the data to C++ by embedding python. In my project I use absolute paths as pythons search path to load the script from 'C'.
XCode project/
-- Python.framework/
-- python/
---- mypython.py
-- python_interface.c
-- main.cpp
My questions are:
Q1: I have brew Python available but this isn't seen from XCode, instead the system supplied one is. This isn't a problem for now but I would eventually like to know how to point to my chosen installation.
I have bundled the brew Python.framework into my project so it links successfully. I know it doesn't invoke this because if I specify my module path incorrectly it complains the system python can not find it. Also, 'system(which python)' reports '/usr/bin/python'.
Q2: How do I specify relative search paths to python within XCode, i.e. to locate my local python module from 'C' code within my project?
Q3: How do I determine the absolute path of python 'requests' installation at runtime? My python module imports this and it could be different than what I specify.
Currently, I use Py_GetPath and Py_SetPath to indicate these using absolute paths, i.e. '/usr/local/lib/python2.7/site-packages' for 'requests'.
I know how to locate the module path within python itself (Find path of module without importing in Python) but this is not what I want to do. I need to know the path before my script is run.
As mentioned I am embedding python, so I am making the call from 'C' to my python script (see https://docs.python.org/2/extending/embedding.html?highlight=embedded#pure-embedding).
I have found the following links that show how to get the path of the executable. What I would like is the path of the project and use relative paths from that to locate my python module.
Relative Paths Not Working in Xcode C++
Programmatically retrieving the absolute path of an OS X command-line app
I have found this posting; Relative imports for the billionth time. My search path from 'C' code to my python script is relative but I believe this post is mainly about python scripts importing other modules relative to each other.
Q4: The result of adding or linking Frameworks to an XCode project is the same. In my case the Python.framework appears in the 'Project navigator' and it is added to the 'Link Binaries With Libraries' section. Yet the following two articles indicate that there is a difference between the two. It is not the size of the executable as I have tried both methods and this remains the same.
https://developer.apple.com/library/ios/recipes/xcode_help-structure_navigator/articles/Adding_a_Framework.html
This states;
"The frameworks you add this way are third-party-built bundles containing the framework’s object code and runtime resources. See related articles for information about linking to a framework without adding it to the project."
and contains a link to "Linking to a Library or Framework", whose url seems to contradict this (AddingaLibrarytoaTarget).
https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/AddingaLibrarytoaTarget.html#//apple_ref/doc/uid/TP40010155-CH17
Thanks.
Some answers to my questions
I reorganised my project and created my own Makefile using various sources on google. This was because I wanted to port my project as I couldn't answer the above questions. I had worked with Makefiles some years before but I am relatively new to XCode.
To create my Makefile these are the resources I used;
https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
C-library not linking using gcc/g++
https://www.daniweb.com/programming/software-development/threads/124637/makefile-for-c-one-file-programs
https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables
http://www.puxan.com/web/blog/HowTo-Write-Generic-Makefiles
https://www.gnu.org/software/make/manual/
http://nuclear.mutantstargoat.com/articles/make/#building-c-c-programs
https://www.gnu.org/software/make/manual/html_node/index.html
The next step is to automate the process of generating Makefiles;
http://www.ifnamemain.com/posts/2014/Mar/13/autoconf_automake/
New Makefile project structure
project/
-- Debug/ or Release/
-- Makefile
-- obj/
---- target .o files
-- python/
---- .py files
-- src/
---- C/C++ files incl headers
Makefile
# https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables
# $# Contains the target file name.
# $< Contains the first dependency file name.
# $^ The names of all the prerequisites, with spaces between them.
# Produces a Release build by default, or Debug build with ‘make debug’
EXEC = $(BUILD_DIR)/my_exe_name
CCFLAGS=-c -Wall
CXXFLAGS=-c -Wall -std=c++11
BINARY_DIR=Obj
BUILD_DIR=Release
PYTHON_CCFLAGS=$(shell python2.7-config --cflags)
PYTHON_LDFLAGS=$(shell python2.7-config --ldflags)
CPP_FILES := $(wildcard src/*.cpp)
C_FILES := $(wildcard src/*.c)
CPP_OBJ_FILES := $(addprefix $(BINARY_DIR)/,$(notdir $(CPP_FILES:.cpp=.o)))
C_OBJ_FILES := $(addprefix $(BINARY_DIR)/,$(notdir $(C_FILES:.c=.o)))
C_HEADERS = $(filter-out $(addsuffix .h, $(basename $(SOURCE_FILES))), $(wildcard src/*.h))
CPP_HEADERS = $(filter-out $(addsuffix .h, $(basename $(SOURCE_FILES))), $(wildcard src/*.hpp))
### Take the BUILD_DIR as a dependency but ignore it’s timestamp
### as it will change whenever something is written into it
$(EXEC): $(C_OBJ_FILES) $(CPP_OBJ_FILES) | ${BUILD_DIR}
#echo [ $(EXEC) ]
$(CXX) $(LD_FLAGS) $(PYTHON_LDFLAGS) -o $(EXEC) $^
### The objects in the BINARY_DIR folder require the BINARY_DIR to be created
### as well as any changes to the other dependencies
$(BINARY_DIR)/%.o: src/%.cpp $(CPP_HEADERS) $(C_HEADERS) | ${BINARY_DIR}
#echo [ make $# ]
$(CXX) $(CXXFLAGS) $(C11_FLAGS) -o $# $<
$(BINARY_DIR)/%.o: src/%.c $(C_HEADERS) | ${BINARY_DIR}
#echo [ make $# ]
$(CC) $(CCFLAGS) $(PYTHON_CCFLAGS) -o $# $<
${BINARY_DIR}:
mkdir $(BINARY_DIR)
$(BUILD_DIR):
mkdir $(BUILD_DIR)
### clean the targets. We can have either Debug or Release but I don’t know
### how to specify either in one line, i.e. we don’t want to do ‘make clean debug’
### to specify the Debug folder
.PHONY: clean cleanmsg cleanrel cleandeb
clean: cleanmsg cleanrel cleandeb
rm -r -f $(BINARY_DIR)
cleanmsg:
#echo Cleaning product and all .o files
cleanrel:
rm -r -f Release
cleandeb:
rm -r -f Debug
# Debug build
# Ensure these are last. I had them below the original decl of the flags
# and they were always set! Now you have to ‘make debug’ for it to take effect
.PHONY: debug
debug: CCFLAGS += -DDEBUG -g
debug: CXXFLAGS += -DDEBUG -g
debug: BUILD_DIR=Debug
debug: $(EXEC)
Using XCode with new Makefile project
To continue using XCode to develop my project I created an XCode project over my Makefile project. See http://hiltmon.com/blog/2015/08/01/simple-c-plus-plus-from-makefiles-to-xcode-builds/
Answers
By doing this I am able to somewhat answer the above questions. Q3 is still unanswered.
A1: Create a Makefile project and within it state the platform specified python installation. This way you do not need to bundle it into your XCode project.
See https://docs.python.org/2/extending/embedding.html?highlight=embedded#compiling-and-linking-under-unix-like-systems.
A2: Make the XCode project relative so your product resides in your project. Not the best answer if you want your exe installed in /usr/local/bin.
See How to change output directory for a target (gp_coder's answer).
My Makefile stores the exe in either ./Release/ (make), or ./Debug/ (make debug). So does XCode but with different leading directories that are several levels deep. To change this, simply specify the current dir '.' in XCode for the Targets "Project Settings>Advanced>Custom>Products" destination directory, this will then match the Makefile.
My python search path is set to
:../python:/usr/local/lib/python2.7/site-packages
'../' because my exe is in ./Debug or./Release and python/ is relative to that.
However, if you were to invoke the exe from the cmdline one dir up it wouldn't work. e.g. ./Release/my_exe_name. This is because it is taking the current dir and using the search path in relation to that.
It would be better to store and set the absolute path. See Where to store application data (non-user specific) on Linux
I posted a question on this before I realised the answer; How to set relative project path in XCode when target is /usr/local/bin
The second path is for my python requests directory. Q3 refers to this.
A3: Don't know. Still have to work out how to pass my installed python module path into my C code at runtime BEFORE invoking python, as this makes up my python search path. This value changes based on your installation.
A4: This wasn't really a question but a confusion. Specify this in your Makefile to avoid bundling.
I'm trying to create a makefile for a suite of programs that I am working on. The programs are all written in fortran and the source files are contained in different directories. I can't seem how to figure out how to get things to work. My current sumfile is
#Compiler and compiler flag variables
FCOMP=/usr/local/bin/gfortran
F_FLAGS=-O2 -fbounds-check -Wall
F_FLAGSDB=-g -fbounds-check -Wall
#paths to libraries
COMMON_LIB=/usr/local/lib/libspc_common.a
SPICE_LIB=/usr/local/lib/spicelib.a
# Paths to directories
BIN_DIR=BIN
# Get file names of component source files
#get names of files in src1
FORT_FILES=$(wildcard ./SRC1/*.f)
#get names of files in src2
FORTFILES+=$(wildcard ./SRC2/*.f)
#get names of files in src3
FORTFILES+=$(wildcard ./SRC3/*.f)
#get file names for output
EXE_FILES=$(addprefix $(BIN_DIR),$(notdir $(patsubst %.f, % , $(FORTFILES))))
# make commands
# Set the default option to compile the library with optimization
default: all
# create all command
all: $(EXE_FILES)
#echo toolkit has been built with optimization
#If compiling for debugging replace the compiler flags to remove optimization and add debugging
debug: F_FLAGS=$(F_FLAGSDB)
#Run compiler with debugging flags
debug: $(EXE_FILES)
#echo toolkit has been built with debugging
# Compile all of the source files into executables
$(EXE_FILES): % : %.f
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $(BIN_DIR)/$#
# install the library in /usr/local/lib
install:
cp -p $(BIN_DIR)* /usr/local/bin/toolkit/
# remove executable files for a clean build
clean:
rm $(BIN_DIR)*
The problem I am running into is that I get the following error when I try to run make:
make: *** No rule to make target `Display.f', needed by `Display'. Stop.
which I am assuming is because I have lost the directory that the source file comes from. Can someone help me here? I am totally stuck and don't know how to proceed.
In addition (this is more a general question about make), is there a way to tell make to recompile everything if the COMMON_LIB changes?
Thanks for your help!
Suppose your source files are
SRC1/alpha.f
SRC1/beta.f
SRC2/gamma.f
SRC3/delta.f
1) There is a flaw here:
EXE_FILES=$(addprefix $(BIN_DIR),$(notdir $(patsubst %.f, % , $(FORTFILES))))
This will produce
BINalpha BINbeta BINgamma BINdelta
when I think you intended
BIN/alpha BIN/beta BIN/gamma BIN/delta
A simple fix:
EXE_FILES=$(addprefix $(BIN_DIR)/,$(notdir $(patsubst %.f, % , $(FORTFILES))))
2) Now look at the static pattern rule:
$(EXE_FILES): % : %.f
...
So to build BIN/alpha, Make must first find BIN/alpha.f, which doesn't exist. To make it look for alpha.f, do this:
$(EXE_FILES): $(BIN_DIR)/% : %.f
...
3) How to find the sources?
You could do some delicate coding to help Make remember where it found alpha.f, but there's no need when we can use the vpath directive:
vpath %.f SRC1 SRC2 SRC3
4) One last look at that rule:
This command:
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $(BIN_DIR)/$#
Will produce e.g. BIN/BIN/alpha, which is silly. A non-PHONY Make rule should produce a file whose name is the target of the rule. It prevents a lot of trouble.
$(FCOMP) $(F_FLAGS) $^ $(COMMON_LIB) $(SPICE_LIB) -o $#
A few further refinements may be possible, once you have this working perfectly.
I'm confronting the Linux kernel build system (Kbuild, kernel ≥2.6.28) with the directory structure and build system for a larger project. Our project contains an out-of-tree Linux kernel module, and our directory structure looks like this (simplified, obviously):
checkout/src/common/*.c source files (common to Linux and other platforms)
checkout/src/linux-driver/*.c source files (for the Linux kernel driver)
checkout/build/linux/Kbuild Kbuild
tmp/linux-2.6.xx/ where the Linux kernel is unpacked and configured
output/linux-arm-debug/ where object files must end up
The build process must not modify anything under checkout, and building the module must not modify anything under tmp/linux-2.6.xx. All output files must end up under output/linux-arm-debug (or whatever architecture and debug variant was selected at build time).
I've read kbuild/modules.txt, and started to write my Kbuild file:
MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)
obj-m += $(MOD_OUTPUT_DIR)/foo_mod.o
$(MOD_OUTPUT_DIR)/our_module-objs := $(MOD_OUTPUT_DIR)/foo_common.o $(MOD_OUTPUT_DIR)/foo_linux.o
This handles storing the object files in a different directory from where Kbuild lives. Now how can I specify that foo_common.o needs to be compiled from …/checkout/src/common/foo_common.c and foo_linux.o from …/checkout/src/linux-driver/foo_linux.c?
Here is a Makefile which does out of source-tree builds for out of kernel-tree modules (adapted from #Mark's comment)...
KDIR ?= /lib/modules/$(shell uname -r)/build
BUILD_DIR ?= $(PWD)/build
BUILD_DIR_MAKEFILE ?= $(PWD)/build/Makefile
default: $(BUILD_DIR_MAKEFILE)
make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) modules
$(BUILD_DIR):
mkdir -p "$#"
$(BUILD_DIR_MAKEFILE): $(BUILD_DIR)
touch "$#"
clean:
make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) clean
Note: You still need a Kbuild file...
obj-m += my_driver.o
I had a similar problem. I modified linux_2_6_34/scripts/Makefile.build as follows.
ifdef SRCDIR
src := $(SRCDIR)
else
src := $(obj)
endif
SRCDIR is the directory source.
To compile the module, run
make -c $(KDIR) M=$(Your_output_dir) SRCDIR=$(your source directory)`
My inelegant but effective solution is to copy the source files into the output tree.
FOO_SOURCES_DIR = $(src)/../../../checkout/src
FOO_MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)
# Specify the object files
obj-m += $(FOO_MOD_OUTPUT_DIR)/foo_mod.o
FOO_MODULE_OBJS := $(FOO_MOD_OUTPUT_DIR)/foo_common.o $(FOO_MOD_OUTPUT_DIR)/foo_linux.o
$(FOO_MOD_OUTPUT_DIR)/foo_mod-objs := $(FOO_MODULE_OBJS)
# Where to find the sources
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_common.c: $(FOO_SOURCES_DIR)/common/foo_common.c
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_linux.c: $(FOO_SOURCES_DIR)/linux-driver/foo_linux.c
# Rules to copy the sources
FOO_COPIED_SOURCES = $(patsubst %.o,$(src)/%.c,$(FOO_MODULE_OBJS))
$(FOO_COPIED_SOURCES):
$(Q)mkdir -p $(#D)
cp -f $< $#
clean-files += $(FOO_COPIED_SOURCES)
clean-dirs += $(FOO_MOD_OUTPUT_DIR)
While you haven't mentioned what you've tried so far (or whether you found a solution already), it looks like you just need to continue further down the modules.txt file a bit -- to Section 4.3:
--- 4.3 Several Subdirectories
kbuild can handle files that are spread over several directories.
Consider the following example:
.
|__ src
| |__ complex_main.c
| |__ hal
| |__ hardwareif.c
| |__ include
| |__ hardwareif.h
|__ include
|__ complex.h
To build the module complex.ko, we then need the following
kbuild file:
--> filename: Kbuild
obj-m := complex.o
complex-y := src/complex_main.o
complex-y += src/hal/hardwareif.o
ccflags-y := -I$(src)/include
ccflags-y += -I$(src)/src/hal/include
As you can see, kbuild knows how to handle object files located
in other directories. The trick is to specify the directory
relative to the kbuild file's location. That being said, this
is NOT recommended practice.
For the header files, kbuild must be explicitly told where to
look. When kbuild executes, the current directory is always the
root of the kernel tree (the argument to "-C") and therefore an
absolute path is needed. $(src) provides the absolute path by
pointing to the directory where the currently executing kbuild
file is located.
A bit late, but it looks like O= flag is what you need.
You can set the environment variable KBUILD_OUTPUT. This functions similar to the O= option; however, since it's an environment variable, it can span multiple makefiles where O= can't be passed or an out-of-directory module needs to be built. I was having this same issue with trying to build a set of compat-wireless modules and I needed to use O= for the actual kernel image build.