building more than one target in makefile - makefile

I need a GNU makefile to generate different libraries based on the file list.
My directory structure looks like :
-parent_dir
-inc
-src
-lib
-build_dir
I have all the sources dumped in the src dir.
I need to make three different target based on different files.
SOURCES_TARGET_1 := 1.cpp \
2.cpp
SOURCES_TARGET_2 := 3.cpp \
4.cpp
SOURCES_TARGET_3 := 5.cpp \
6.cpp
All the targets have the same rule. Only thing that differs is the include files and source file list.
How can i do this in a generic way by defining rules that can be applied to src list.

Related

Makefile for building and outputting in a bunch of different folders

I have a directory that contains a bunch of folders, all of which contain a .go file that I will want to build, and I'm trying to create a Makefile that can accomplish this. These are the requirements I'm looking to fill:
1.) I want this to be dynamic so that the number of folders can grow and change, and I won't need to update the Makefile every time.
2.) I also want the .go files to be able to have different names than the folder that holds them (for example, if the folder is lambda1 then the .go file shouldn't need to be named lambda1.go).
3.) Lastly, I want each binary to be output in the same folder that its source file is in.
This is what the folder structure looks like with the built binaries included:
lambdas
lambda1
--first.go
--first (binary)
lambda2
--second.go
-- second (binary)
lamba3
--third.go
--third (binary)
...
This is what the actual build commands look like:
GOOS=linux go build -o lambdas/lambda1/first lambdas/lambda1/first.go
GOOS=linux go build -o lambdas/lambda2/second lambdas/lambda2/second.go
and then in a later step I need to zip that binary like this:
zip lambdas/lambda1/function.zip lambdas/lambda1/first
zip lambdas/lambda2/function.zip lambdas/lambda2/second
It seems like what I need is to loop through the lambdas directory, and for each directory, get the name of the .go file, and then using those dir paths and file names, I could create each build command.
I'm brand new to Makefiles and have been trying to figure this out for about a day now and am not having luck. Thank you for any help.
What about something like this:
# Find all the .go files under lambdas
GOFILES := $(shell find lambdas -name \*.go)
GOPROGS := $(GOFILES:%.go=%)
GOZIPS := $(GOPROGS:%=%.zip)
# We want to build all the progs and zips
all: $(GOPROGS) $(GOZIPS)
# How to build each prog from a .go file
$(GOPROGS): % : %.go
GOOS=linux go build -o $# $<
# How to build each zip from a prog file
$(GOZIPS) : %.zip : %
zip $# $<
I'm using static pattern rules here but you could use normal pattern rules as well.
Oh I didn't notice you want the zip files to have the same name. This of course assumes that there will be only one .go file, and hence one program, in every directory? Seems limited.
This is not so simple because the names don't match. Although it could be done via separate rules if you really wanted to, the simplest thing to do is just put both the compile and zip into the same rule:
# Find all the .go files under lambdas
GOFILES := $(shell find lambdas -name \*.go)
GOPROGS := $(GOFILES:%.go=%)
# We want to build all the progs
all: $(GOPROGS)
# How to build each prog from a .go file
$(GOPROGS): % : %.go
GOOS=linux go build -o $# $<
zip $(#D)/function.zip $#

How to create this makefile? Sources in subdirectories, separate output path, linking objects in subdirectories

Is there a way to create a makefile that does this?
I gave up after trying to follow the docs and lots of trial and error so I'll just post a description of what the makefile should do.
general directory structure:
src/ - contains c source files in various subdirectories (written manually by maintainer)
inc/ - contains h header files in subdirectories matching src (written manually by maintainer)
obj/ - contains o header files in subdirectories matching src (autogenerated by a make call)
bin/ - should contain binary (autogenerated by a make call)
makefile
so for example at a given point of time the project might look like
src/
main.c
sub1/
other1.c
other2.c
sub2/
sub3/
other3.c
inc/
sub1/
other1.h
other2.h
sub2/
sub3/
other3.h
obj/
main.o
sub1/
other1.o
other2.o
sub2/
sub3/
other3.o
bin/
release
makefile
(probably not relevant: Note that main doesn't have a header file but most likely every other c file will have a matching h file.)
I want to be able to call make, and have it:
use gcc to recompile only changed c files into respective o files in obj/, generating missing subdirectories if needed.
for example, from the above state, if I add a new subdirectory sub4 inside src/sub1/, and then create other4.c inside src/sub1/sub4/, I would like make to generate sub4 inside obj/sub1/ and then generate other4.o inside obj/sub1/sub4/
create a binary at bin/release by linking all object files (from all subdirectories in obj/)
I don't want to have to change the makefile each time I add directories in src
I don't want to manually have to create directories in obj, the makefile should take care of it. if this is not possible, maybe have it rename all obj o files to a flat naming pattern? i.e. obj/sub2_sub3_other3.o instead of obj/sub2/sub3/other3.o (although this can cause issues)
probably not relevant here, but the C files use include statements in this format:
#include "sub2/sub3/other3.h"
so -I./inc would be included in the gcc call. Whereas the linker would receive inputs like -s -O3. I want to make sure those options (compiler options, linker options) are listed at the top of the makefile in variables (CFLAGS, LDFLAGS, etc) and not passed incorrectly to the targets.
is this even possible? if not, what's the closest possible?
Also, can this makefile be made to work on both POSIX systems and on Windows based systems? e.g. work the same on linux/gcc and win/mingw

Building an out-of-tree linux kernel module with separate output directory

I want to build an out of tree kernel module with the output directory being separate from my source directory? How would I do this? I'm willing to go any route. I'm okay with minimal changes to the kernel build system, I'm okay with copying source files (however I do not want to rebuild if I haven't made any changes to the source files and this doesn't work if I copy source files normally), and I'm okay with setting a parameter or something.
many many people face this problem, including me.
To support build external module at separate output directory.
I modify the kbuild:
firstly, modify src variable at scripts/Makefile.build and scripts/Makefile.clean
-src := $(obj)
+src := $(if $(KBUILD_EXTMOD_SRC),$(KBUILD_EXTMOD_SRC)$(patsubst $(KBUILD_EXTMOD)%,%,$(obj)),$(obj))
secondly, modify scripts/Makefile.modpost
-src := $(obj)
+src := $(if $(KBUILD_EXTMOD_SRC),$(KBUILD_EXTMOD_SRC),$(obj))
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
-include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \
- $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile)
+include $(if $(wildcard $(src)/Kbuild), \
+ $(src)/Kbuild, $(src)/Makefile)
then build external module like this:
make -c $(kernel_src) M=$(extmod_outpu_dir) KBUILD_EXTMOD_SRC=$(extmod_src_dir) modules

Out of tree kernel modules: Multiple module, single Makefile, same source file, different build options

I am building a set of Linux kernel modules using shared source code. From what I understand, the Makefile has to be named "Makefile" so I have to use the same Makefile to build two different modules. How can I build two different modules, within the same Makefile, with the same source code, but with two different build options?
For example, my modules are called module1 and module2. So I have the following line to define them:
obj-m := module1.o module2.o
Among other files, both module1 and module2 need to use the same source file code.c, but built with different build options. So say for example, the Makefile contains the following lines:
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
I want module1_code.o and module2_code.o to be built from code.c, but with different options. Specifically, I want one module1_code.o with a macro defined -DPREPROCEFFOR_FLAG=1, and module2_code.o built without the macro.
From what I understand, the system of Makefiles used in Linux implicitly infers that for an object file called "code.o", the source file is called "code.c", so how would I achieve this? Is is possible? Is there a better way to do this?
You have a problem here, because you obviously have code.c being compiled differently when -DPREPROCEFFOR_FLAG=1 is defined, but once it's compiled into code.o, make won't care about preprocessor flags or whatever because code.o will be already up to date.
You need a way to build code.c to different object files with different C flags. There's probably a clean way to do this (had no chance with O= for out of tree modules), but here's my innelegant yet effective solution for the moment:
my_modules:
cp code.c code_noflags.c
cp code.c code_withflags.c
make -C $$KDIR M=$$PWD modules
rm code_noflags.c code_withflags.c
# module objects
obj-m := module1.o module2.o
# module1 specifics
module1-y := code_withflags.o
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1
# module2 specifics
module2-y := code_noflags.o
Just call:
$ make KDIR=/path/to/kernel
You can verify the preprocessor flag is passed to the source file for the right object with:
$ make KDIR=/path/to/kernel V=1 | grep PREPRO
You could also have two separate directories for each module, if this is possible, and have a symbolic link code.c in each one pointing to the common real code.c. However, this is still hackish and doesn't feel right.
One simple solution is, continuing from your Makefile
obj-m := module1.o module2.o
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
to add two more source files, module1_code.c and module2_code.c.
Then module1_code.c just looks like:
#define PREPROCEFFOR_FLAG 1
#include "code.c"
and module2_code.c is:
#include "code.c"
Or if you like, change the names in the Makefile and source files so that the second include without a define isn't necessary. Also you could make the two source files nothing but an include and use the CFLAGS_module1_code.o variable to add the -D... option to the compiler if you prefer.
This is similar to what happens in the upstream kernel with arch/x86/boot/video-vesa.c and arch/x86/realmode/rm/video-vesa.c etc., where the realmode file just contains:
#include "../../boot/video-vesa.c"
and the video-vesa.c code ends up getting compiled twice with different compiler flags.
This seems preferable to copying the source files, since you end up with a mess there if you want to use the O=... option to the kernel build to keep a clean source tree and build in a separate object tree.

Building an out-of-tree Linux kernel module in a separate object directory

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.

Resources