Change default directory src for openwrt compiling package - makefile

I'm creating a package for openwrt that contains several modules.
The package compiles right if the structure is:
package_name
. Makefile<s>.txt</s>
. files
. src
+ CMakeLists.txt
+ Module1
+ Module2
+ ...
+ Modulen
But if I change the name src by modules it shows me errors. I know the default structure search for src directory, but,
what should I add to my Makefile.txt to change default value src to any other one?
Thank you.

The OpenWRt package structure can be found here. The interresting part for you is Bundle source code with OpenWrt Makefile.
(I am afraid the Makefile should be just Makefile without txt extension. It would be helpful if you could post your complete Makefile - but I will try without it. Also please indicate the OpenWRT version you are using, the answer can be version-dependent)
I have found in include/package-defaults.mk the following [OpenWRT 19.07.1]:
Build/Patch:=$(Build/Patch/Default)
ifneq ($(strip $(PKG_UNPACK)),)
define Build/Prepare/Default
$(PKG_UNPACK)
[ ! -d ./src/ ] || $(CP) ./src/. $(PKG_BUILD_DIR)
$(Build/Patch)
endef
endif
This means to me, that either you:
define PKG_UNPACK in your Makefile as follows: PKG_UNPACK=$(CP) ./modules/. $(PKG_BUILD_DIR)
override default Prepare section as follows (or copy recursive, depending on your structure):
.
define Build/Prepare
$(call Build/Prepare/Default)
$(CP) ./modules/* $(PKG_BUILD_DIR)/
endef

Related

Bash : use variable in variable (nested loop)

I have a makefile and I want to compile each of my vhdl files in the correct library. And there is my code :
$(DEBUG)for core_lib in $(CORE_LIB_LIST); \
do for core_lib_src_vhd in $($$core_lib.VHDL_SRC_FILES_LIST); \
do $(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work $$core_lib $(BLOCK_PATH)/cores/$$core_lib_src_vhd; \
done; \
done;
But $($$core_lib.VHDL_SRC_FILES_LIST) is unrecognized.
I guess that in $($$core_lib.VHDL_SRC_FILES_LIST) core_lib is a shell variable and you want make to expand it first, and then expand the make variable which name is ${core_lib}.VHDL_SRC_FILES_LIST. This is not how make works. You cannot expect make to expand shell variables.
Instead you should rely on make variables only. Assuming:
make variable CORE_LIB_LIST is the list of libraries,
for each library LIB there is a make variable LIB.VHDL_SRC_FILES_LIST listing the source files,
the source files are in $(BLOCK_PATH)/cores/,
you could try this:
.PHONY: compile-all-libs
# $(1): library
define COMPLIB_rule
.PHONY: compile-$(1)
compile-$(1):
$$(DEBUG)$$(COMPILER_VHDL) $$(CC_VHDL_OPTIONS) $$(COVER_OPTIONS) -work $(1) $$(addprefix $$(BLOCK_PATH)/cores/,$$($(1).VHDL_SRC_FILES_LIST))
compile-all-libs: compile-$(1)
endef
$(foreach LIB,$(CORE_LIB_LIST),$(eval $(call COMPLIB_rule,$(LIB))))
Explanation: the define COMPLIB_rule ... endef is just another way to define a make variable named COMPLIB_rule. The $(foreach ... construct must be put flat in the Makefile (not in a recipe). It iterates over the words in the definition of make variable CORE_LIB_LIST. For each word LIB, it replaces $(1) by LIB in the definition of COMPLIB_rule (it also replaces every $$ by a single $) and it instantiates the result as a regular make rule. If the make variable CORE_LIB_LIST evaluates as a b, for instance, the result will be the same as:
.PHONY: compile-a
compile-a:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work a $(addprefix $(BLOCK_PATH)/cores/,$(a.VHDL_SRC_FILES_LIST))
compile-all-libs: compile-a
.PHONY: compile-b
compile-b:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work b $(addprefix $(BLOCK_PATH)/cores/,$(b.VHDL_SRC_FILES_LIST))
compile-all-libs: compile-b
So, if you type make compile-all-libs, make will try to build compile-a and compile-b, the two pre-requisites of compile-all-libs. In order to build compile-a it will execute the recipe:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work a $(addprefix $(BLOCK_PATH)/cores/,$(a.VHDL_SRC_FILES_LIST))
which will compile in library a all source files listed in make variable a.VHDL_SRC_FILES_LIST and found in directory $(BLOCK_PATH)/cores. Same with compile-b.
But of course, it would be much better if you were recompiling only what's needed (that is, source files that changed since the last time they were compiled). This can be done with empty tag files that keep track of the last time a source file was compiled:
.PHONY: compile-all-libs
# $(1): library
# $(2): source file basename
define COMPLIB_rule
$$(BLOCK_PATH)/cores/$(1).$(2).tag: $$(BLOCK_PATH)/cores/$(2)
$$(DEBUG)$$(COMPILER_VHDL) $$(CC_VHDL_OPTIONS) $$(COVER_OPTIONS) -work $(1) $$< && \
touch $$#
compile-all-libs: $$(BLOCK_PATH)/cores/$(1).$(2).tag
endef
$(foreach LIB,$(CORE_LIB_LIST),$(foreach FILE,$($(LIB).VHDL_SRC_FILES_LIST),$(eval $(call COMPLIB_rule,$(LIB),$(FILE)))))
clean:
$(DEBUG)rm -f $(BLOCK_PATH)/cores/*.tag
Explanation: there, the foreach-foreach-eval-call iterates over library/source file pairs. For each LIB-FILE pair, it replaces $(1) by LIB and $(2) by FILE in the definition of COMPLIB_rule (it also replaces every $$ by a single $) and it instantiates the result as a regular make rule. All this declares all LIB.FILE.tag files as pre-requisites of target compile-all-libs and declares the rule to build the tag by compiling FILE in LIB and touching the tag file. This is just like if, for each source FILE of library LIB, you added this to your Makefile:
$(BLOCK_PATH)/cores/LIB.FILE.tag: $(BLOCK_PATH)/cores/FILE
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work LIB $< && \
touch $#
compile-all-libs: $(BLOCK_PATH)/cores/LIB.FILE.tag
Just type make compile-all-libs and see: make will build all tag files, that is, compile each source file in its own library and touch the tag file. As the VHDL source file is a pre-requisite of the tag file, it is only if the VHDL source file is more recent than the tag file that the recipe will be executed. This is the same as the .o / .c dependency for C programs. The only difference is that we do not use the compilation result itself (.o) because we do not really know what it is with Modelsim. Instead, we create a tag file, just for this purpose. Side effect: it would be exactly the same with a different VHDL compiler/simulator.
This would even give you the possibility to declare dependencies between your source files: if $(BLOCK_PATH)/cores/foo.vhd must be compiled in library FOO_LIB before $(BLOCK_PATH)/cores/bar.vhd can be compiled in library BAR_LIB, you could add:
$(BLOCK_PATH)/cores/BAR_LIB.bar.vhd.tag: $(BLOCK_PATH)/cores/FOO_LIB.foo.vhd.tag
to your Makefile. And there are also many possible improvements like, for instance, per-library goals...

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

Make: why do I get error saying "no such file or directory"

When I tried my makefile, I got error saying that No such file or directory, but my directory is right there, what do I do wrong? Thanks.
my project structure :
dev |--- ev
|--- display
|--- install ( makefile is here, try to call makefiles in ev and display folder)
My makefile :
MODULES :=ev display
SRC_DIR :=$(addprefix ../, $(MODULES))
BUILD_DIR:=$(addsuffix /build, $(SRC_DIR))
x:=../ev ------> add temporarily just for test,
------> the same error if x:=$(HOME)/dev/ev
INSTALL_DIR:=EX Frameworks Add-ons
INSTALL_DIR:=$(addprefix $(HOME)/EX/, $(INSTALL_DIR))
vpath %.cpp %.java $(SRC_DIR)
.PHONY: all clean
checkdirs: $(INSTALL_DIR)
$(INSTALL_DIR):
#echo "INSTALL DIR"
#mkdir -p $#
define make-goal
$1:
#echo "start building each part"
cd $# && make -f Makefile_new.osx clean
cd $# && make -f Makefile_new.osx package
endef
clean:
#echo "clean up"
#echo "BUILD_DIR IS $(BUILD_DIR)"
#rm -rf $(BUILD_DIR)
all:
#echo "start build subdirectory"
#echo "SRC_DIR IS $(SRC_DIR)"
#echo "x is $(x)"
$(call make-goal, $(x))) ----> when it comes to here, I got error message
The error messages:
x is ../ev
../x:
make: ../ev:: No such file or directory.
I guess it is about relative path, because I call this makefile from Install folder, then $(x) can't be found from Install folder, but when I tried to make a folder named ev (Install/ev), I still got the same error.
I think it must be something basic I missed here, but what it is.
Thanks.
Update:
I am trying to build a project which includes several sub-projects. the structure is:
dev |---- ev
|---- edf
|----- dt
|------af
|------Install
Inside of Install, I have a makefile, which is at the top level. The makefile in Install folder will call makefiles in other folders to build different subjects,
Ideally, I want to build every sub projects without touching sources. My sources include c++ and java code.
It's not clear what you're trying to do. Also due to some indentation hiccups I can't be sure, but you appear to be defining a variable make-goal that contains a template for a make rule, then using it with $(call ...) inside the recipe for the all target. That cannot work: you cannot create a make rule inside the recipe for another make rule!
The reason this fails is that the $(call ...) is expanding to content which is added to the recipe of the all target, so instead of creating a new make rule it's treating the result as a shell script. The first line is $1:, and you passed in ../ev, so make is trying to run the command ../ev: just as the error shows you.
If you describe what you want to do at a higher level we can give you some ideas on how to do it.
ETA:
If you just want your all target to also build a subdirectory, there's no need for all this complex GNU make advanced capabilities. That stuff is only needed when you get to guru-level makefile creation. Simple "build a target after another target is finished" is the exact thing make was designed to do: nothing special is needed to do that.
For example:
.PHONY: all $(SRC_DIR)
all: $(SRC_DIR)
$(SRC_DIR):
#echo "start building $#"
cd $# && $(MAKE) -f Makefile_new.osx clean
cd $# && $(MAKE) -f Makefile_new.osx package
This is still a pretty non-standard setup but I think it will work the way you want. Remember you'll have to either move the all target up to be the first one in the makefile, or you'll have to run make all explicitly: make only builds the first target in the makefile unless you give it specific targets on the command line.

Header include path in files generated by `protoc`

When I call protoc like this
protoc --cpp_out=. path/to/test.proto
the files
path/to/test.pb.cc and
path/to/test.pb.h
are generated which is what I want. But, since the cc needs the h, the h is included like this
#include "path/to/test.pb.h"
which is not what I want. The background is that my build tool (scons) calls protoc from the project's root and not from the directory which includes the source files. I found no obvious option in the manpage or the help text.
So my next idea was to consider this as "correct" and adjust my build system, but: The two files are siblings in the directory tree, so when one includes the other, no path is needed. Even compiling by hand fails.
Can someone help me with that?
Doing find-replace on generated files is most likely easier
than reorganization of your build system (use sed command on Linux/unix).
What I ended up doing for my project is as follows:
Create a pb/ directory at the same level as your include/ and src/ directories.
Put your .proto files in there, and create a makefile. Write the following in it:
CXX = g++
CXXFLAGS = -O3
PROTOBF = $(shell find ./ -name '*.proto')
SOURCES = $(subst proto,pb.cc,$(PROTOBF))
OBJECTS = $(subst proto,pb.o,$(PROTOBF))
default: $(OBJECTS)
#echo -n
$(SOURCES): %.pb.cc : %.proto
protoc --cpp_out=. $<
$(OBJECTS): %.pb.o : %.pb.cc
$(CXX) $(CXXFLAGS) -c $< -o $#
Which will essentially generate and build the protobuffer files when invoked.
In your main makefile, simply add the following include path: -Ipb/.
And when including a protocol buffer header, use #include <whatever.pb.h>.
Add the object files generated in pb/ to your linking step. Myself I used:
PB_OBJS = $(shell find pb/ -name '*.pb.o')
And gave that to the linker along with the normal object files in obj/.
Then, you can probably call the pb/ makefile from the main makefile if you want to automate it. The important point is that protoc be called from the pb/ directory or the include will be messed up.
Sorry for the ugly makefiles. At least it works, and I hope this helps you...

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