I have touble when including files with makefile for a stm32f4xx - gnu-make

I'am starting using Linux and I have some trouble using some stm32f4 libraries for my project gcc-testing.
All the CMSIS programs needed are inside the STM32F4_Discovery_FW_V1.1.0 and the project is arranged like this:
~
|__
| |
| STM32F4XX
| |
src STM32F4_Discovery_FW_V1.1.0
|
ggc-testing
|
makefile
main.c
stm32f4xx_config.h
stm32_flash.ld
system_stm32f4xx.c
The main.c and the system_stm32f4xx.c use the stm32f4xx.h file that is inside the STM32F4_Discovery_FW_V1.1.0/Libraries/CMSIS/ST/STM32F4xx/Include
The error I get from the terminal is:
Make file console error
My make file:
PROJ_NAME=main
STM_DIR=~/STM32F4XX/STM32F4-Discovery_FW_V1.1.0
STM_SRC = $(STM_DIR)/Libraries/STM32F4xx_StdPeriph_Driver/src
vpath %.c $(STM_SRC)
SRCS = main.c
SRCS += system_stm32f4xx.c
SRCS += $(STM_DIR)/Libraries/CMSIS/ST/STM32F4xx/Source/Templates/TrueSTUDIO/startup_stm32f4xx.s
INC_DIRS = $(STM_DIR)/Utilities/STM32F4-Discovery
INC_DIRS += $(STM_DIR)/Libraries/CMSIS/Include
INC_DIRS += $(STM_DIR)/Libraries/CMSIS/ST/STM32F4xx/Include
INC_DIRS += $(STM_DIR)/Libraries/STM32F4xx_StdPeriph_Driver/inc
INC_DIRS += .
TOOLS_DIR = /opt/gcc-arm-embedded/gcc-arm-none-eabi-4_7-2013q1/bin
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
GDB = arm-none-eabi-gdb
INCLUDE = $(addprefix -I,$(INC_DIRS))
DEFS = -DUSE_STDPERIPH_DRIVER
CFLAGS = -ggdb
CFLAGS += -O0
CFLAGS += -Wall -Wextra -Warray-bounds
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
LFLAGS = -Tstm32_flash.ld
.PHONY: $(PROJ_NAME)
$(PROJ_NAME): $(PROJ_NAME).elf
$(PROJ_NAME).elf: $(SRCS)
$(CC) $(INCLUDE) $(DEFS) $(CFLAGS) $(LFLAGS) $^ -o $#
$(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex
$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
clean:
rm -f *.o $(PROJ_NAME).elf $(PROJ_NAME).hex $(PROJ_NAME).bin
# Flash the STM32F4
flash:
st-flash write $(PROJ_NAME).bin 0x8000000
.PHONY: debug
debug:
# before you start gdb, you must start st-util
$(GDB) $(PROJ_NAME).elf
Hope enyne can help with this.

After gnu make generates a cmd-line (eg gcc), use of a ~ would rely on make executing a shell and the shell expanding an arg with a leading unquoted ~. Based on your line with $(addprefix, try adding a space between -I and ,$(INC_DIRS)
However, the overhead from executing a shell can be undesirable and the extra exec is often easy to avoid; for this case, replace ~ with $(HOME)
Example Makefile :
SUBDIR := some/incdir
TILDE_SUBDIR := ~/$(SUBDIR)
NOT_DELIM := $(addprefix -I,$(TILDE_SUBDIR))
DELIM_INC := $(addprefix -I ,$(TILDE_SUBDIR))
HOME_SUBDIR := $(HOME)/$(SUBDIR)
PHONY: all
all:
#echo NOT_DELIM $(NOT_DELIM)
#echo DELIM_INC $(DELIM_INC)
#echo HOME_SUBDIR $(HOME_SUBDIR)
Output :
NOT_DELIM -I~/some/incdir
DELIM_INC -I /home/user1/some/incdir
HOME_SUBDIR /home/user1/some/incdir

Related

How to use notdir, wildcard and patsubst in a Makefile?

I have the following makefile:
#.SUFFIXES:
#.SUFFIXES: .F90 .cuf .o
ROOT = /home/ccevallos/finalMIT
SRCDIR := $(ROOT)/external/lib_eigesolve
#F90SRC = $(notdir $(wildcard $(SRCDIR)/*.F90))
#F90OBJS = $(patsubst %.F90,%.o,$(F90SRC))
F90OBJS = eigsolve_vars.o toolbox.o zhegst_gpu.o zhemv_gpu.o zhetd2_gpu.o zhetrd_gpu.o zheevd_gpu.o zhegvdx_gpu.o \
dsygst_gpu.o dsymv_gpu.o dsytd2_gpu.o dsytrd_gpu.o dsyevd_gpu.o dsygvdx_gpu.o
#CUFSRC = $(notdir $(wildcard $(SRCDIR)/*.cuf))
#CUFOBJS = $(patsubst %.cuf,%.o,$(CUFSRC))
CUFOBJS = cusolverDn_m.o
FLAGS = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo -Mlarge_arrays
FLAGS2 = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo,maxregcount:64 -Mlarge_arrays
FLAGS3 = -O3 -mp -pgf90libs -Mcuda=cc60,cuda9.1,ptxinfo,nordc,maxregcount:255 -Mlarge_arrays
.PHONY: all
all: lib_eigsolve.a
zhetd2_gpu.o : zhetd2_gpu.F90
pgf90 -c ${FLAGS2} ${OPTFLAGS} $*.F90 -o $*.o
zhemv_gpu.o : zhemv_gpu.F90
pgf90 -c ${FLAGS3} ${OPTFLAGS} $*.F90 -o $*.o
dsytd2_gpu.o : dsytd2_gpu.F90
pgf90 -c ${FLAGS2} ${OPTFLAGS} $*.F90 -o $*.o
dsymv_gpu.o : dsymv_gpu.F90
pgf90 -c ${FLAGS3} ${OPTFLAGS} $*.F90 -o $*.o
cusolverDn_m.o: cusolverDn_m.cuf
pgf90 -c ${FLAGS} ${OPTFLAGS} $*.cuf -o $*.o
%.o: %.F90
pgf90 -c ${FLAGS} ${OPTFLAGS} $*.F90 -o $*.o
lib_eigsolve.a: $(F90OBJS) $(CUFOBJS)
ar rcs $# $^
PHONY: clean
clean:
rm -f lib_eigsolve.a *.mod *.o
This makefile compiles perfectly well, however I basically want to uncomment the lines with # to make this simpler, but when I do that only
ar rcs lib_eigsolve.a
appears in the terminal, with no object file created, and thus lib_eigsolve.a is empty...
Why is it not compiling the object files?
P.S. You can find this Makefile with some modifications here https://github.com/NVIDIA/Eigensolver_gpu
You have a simple typo in $(SRCDIR): the source directory inside Eigensolver_gpu is called lib_eigsolve not lib_eigesolve.
$ cd ~workarea/playground
$ git clone https://github.com/NVIDIA/Eigensolver_gpu.git
$ ls Eigensolver_gpu/
lib_eigsolve LICENSE README.md test_driver
I then proceeded to create a dummy makefile by copy & pasting the relevant lines from your question:
ROOT := $(HOME)/workarea/playground/Eigensolver_gpu
ifndef FIXED
SRCDIR := $(ROOT)/lib_eigesolve
else
SRCDIR := $(ROOT)/lib_eigsolve
endif
F90SRC = $(notdir $(wildcard $(SRCDIR)/*.F90))
$(info F90SRC '$(F90SRC)')
F90OBJS = $(patsubst %.F90,%.o,$(F90SRC))
$(info F90OBJS '$(F90OBJS)')
CUFSRC = $(notdir $(wildcard $(SRCDIR)/*.cuf))
$(info CUFSRC '$(CUFSRC)')
CUFOBJS = $(patsubst %.cuf,%.o,$(CUFSRC))
$(info CUFOBJS '$(CUFOBJS)')
lib_eigsolve.a: $(F90OBJS) $(CUFOBJS)
echo ar rcs $# $^
Test runs:
$ make
F90SRC ''
F90OBJS ''
CUFSRC ''
CUFOBJS ''
echo ar rcs lib_eigsolve.a
ar rcs lib_eigsolve.a
$ make FIXED=1
F90SRC 'dsyevd_gpu.F90 ... zhemv_gpu.F90'
F90OBJS 'dsyevd_gpu.o ... zhemv_gpu.o'
CUFSRC 'cusolverDn_m.cuf'
CUFOBJS 'cusolverDn_m.o'
make: *** No rule to make target 'dsyevd_gpu.o', needed by 'lib_eigsolve.a'. Stop.
Ensure that $(SRCDIR) has no spaces:
SRCDIR := $(strip ${SRCDIR})
ifneq (1,$(words ${SRCDIR}))
$(error Not without further fiddling, friend)
endif
Specifying the path in the wildcard expression looks strange. When you are executing make directly in the srcdir (make -C lib_eigsolve), you should write
F90SRC = $(notdir $(wildcard *.F90))
or
srcdir = .
F90SRC = $(notdir $(wildcard ${srcdir}/*.F90))
when you want to keep your option for out-of-tree builds.

Generating GNU Makefile Rules

So in my project I have a src directory and an obj directory. I'm recursively finding the .c and .cpp files in my src directory, and then its corresponding .o file gets put right in the obj directory. So for example if I have a .cpp file: src/dir1/dir2/file.cpp, its corresponding .o file would be obj/file.o. Then I'm generating the rule to get the .o file from the .cpp file using a make foreach function using this code:
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))
src = $(call rwildcard,src/,*.cpp *.c)
obj = $(patsubst %,obj/%.o,$(basename $(notdir $(src))))
$(info src: [$(src)])
$(info obj: [$(obj)])
game.exe: $(obj)
g++ $^ -o $#
define objFromSrc
$(1): $(2)
$(info $(1) $(2))
g++ -c $(2) -o $(1)
endef
$(foreach t,$(src),$(call objFromSrc,$(patsubst %,obj/%.o,$(basename $(notdir $(t)))),$(t)))
Here is the output for some example files:
src: [src/dir/main.cpp src/dir/dir2/other3.cpp src/dir/other2.cpp src/other.c]
obj: [obj/main.o obj/other3.o obj/other2.o obj/other.o]
obj/main.o src/dir/main.cpp
obj/other3.o src/dir/dir2/other3.cpp
obj/other2.o src/dir/other2.cpp
obj/other.o src/other.c
makefile:20: *** multiple target patterns. Stop.
You can see the obj variable correctly holds the corresponding .o file names. And the objFromSrc function generates a rule where the target and dependency are correct, but yet I get a multiple target patterns error.
Why am I getting this error and how can I fix it?
You are missing the $(eval) to parse the generated makefile code:
$(eval $(foreach t,$(src),...))
I would also suggest to add an empty line at the end of the multi-line define. Leaving this out is usually calling for trouble when $(eval)uating dynamically generated makefile code.
define objFromSrc
$(1): $(2)
$(info $(1) $(2))
g++ -c $(2) -o $(1)
endef
$(info eval $(foreach t,$(src),...))
BONUS CODE: your recipe is a constant so there is no need to re-generate it for every rule. Use a static pattern rule for $(obj) instead:
.DEFAULT_GOAL := game.exe
obj :=
define objFromSrc
$(1): $(2)
obj += $(1)
endef
$(eval $(foreach t,$(src),...))
$(info obj: [$(obj)])
$(obj): %.o:
g++ -o $# -c $<
game.exe: $(obj)
g++ $^ -o $#
Why am I getting this error and how can I fix it?
All these define and $(call ...) in make produce simple strings. You have to eval it to make the make do what you've ordered (i.e. to create the rule $1 : $2):
$(foreach t,$(src),$(eval $(call objFromSrc,$(patsubst %,obj/%.o,$(basename $(notdir $(t)))),$(t))))

Applying patch to file in yocto recipe

I have a yocto recipe to compile a code from github. I modified some files and want to apply a patch to code fetched from github. Following is my recipe for building code.
SUMMARY = "Linux NFC stack for NCI based NXP NFC Controllers"
HOMEPAGE = "https://github.com/NXPNFCLinux/linux_libnfc-nci"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://src/include/linux_nfc_api.h;endline=17;md5=42fdb99b3ff2c12f594b22a774cb7308"
SECTION = "libs"
SRC_URI = "git://github.com/NXPNFCLinux/linux_libnfc-nci.git \
file:///home/pratyush/Desktop/custom_board/drivers/PN7150/linux_libnfc-nci/demoapp-main-patch1.patch"
SRCREV = "7cf539d3d9c0d682c8da5968fbf5615ae9993060"
PV = "2.1+git${SRCPV}"
EXTRA_OECONF =" --enable-pn7150"
S = "${WORKDIR}/git"
inherit autotools
FILES_${PN} += "${libdir}/libnfc_nci_linux-1.so"
FILES_SOLIBSDEV = "${libdir}/libnfc_nci_linux.so"
Following my patch to applied
--- /home/root/PN7150/linux_libnfc-nci/Makefile.am
+++ Makefile.am
## -1,7 +1,7 ##
lib_LTLIBRARIES = libnfc_nci_linux.la
-sbin_PROGRAMS = nfcDemoApp
-nfcDemoApp_DEPENDENCIES = libnfc_nci_linux.la
+sbin_PROGRAMS = readNfc
+readNfc_DEPENDENCIES = libnfc_nci_linux.la
LDFLAGS = -Bstatic
## -9,13 +9,13 ##
LDFLAGS += -L$(openssldir)/lib -lcrypto -lssl
endif
-nfcDemoApp_FLAGS = -I$(srcdir)/demoapp -I$(srcdir)/src/include
+readNfc_FLAGS = -I$(srcdir)/demoapp -I$(srcdir)/src/include
AM_CPPFLAGS = \
-I$(srcdir)/src/include \
$(INCLUDE_PARAMS) \
$(libnfc_nci_linux_la_FLAGS) \
- $(nfcDemoApp_FLAGS)
+ $(readNfc_FLAGS)
if LLCP1_3
AM_CPPFLAGS += \
## -177,7 +177,7 ##
src/service/linux_nfc_api.c \
src/service/linux_nfc_factory_api.c
-nfcDemoApp_SOURCES := \
+readNfc_SOURCES := \
demoapp/main.c \
demoapp/tools.c
## -231,6 +231,6 ##
libnfc_nci_linux_la_LDFLAGS +=-DPN551C2=3
libnfc_nci_linux_la_LDFLAGS += -shared -pthread -ldl -lrt -fPIC -release 1 -versionnfo 0:0:0
-nfcDemoApp_LDFLAGS = -pthread -ldl -lrt -lnfc_nci_linux
+readNfc_LDFLAGS = -pthread -ldl -lrt -lnfc_nci_linux
Thus I want to apply a patch from local to github fetched code. But whenever I try to bitbake apply patch I always get the following error:
can't find file to patch at input line 3
The problem is how you created your patch. The easiest way (if you're used to git) is to use git. Otherwise, diffing two complete source trees is a good and easy way.
One way to solve your issue would be to add ;striplevel=0 to the SRC_URI line. (A strip level of 1 is assumed by bitbake / OE).
Another way would be to modify your patch to start with:
--- a/Makefile.am
+++ b/Makefile.am
That should solve your problem.

GNU make: Generate rules with transformed targets (without eval)

For instance, from variable:
files = dirx/a.cc diry/b.cc dirz/b.cc
I want to effectively have these rules: (without resorting to define/eval)
a_a.o: dirx/a.cc
b_b.o: diry/b.cc
c_c.o: dirz/c.cc
The problem seems unlikely, but this makefile does what you want:
Makefile
VPATH := dirx:diry:dirz
SRCS := a.cc b.cc c.cc
OBJS := $(foreach src,$(SRCS),$(basename $(src))_$(basename $(src)).o)
.PHONY: all clean
.SECONDEXPANSION:
%.o: $$(basename $$(subst _,.,$$*)).cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
all: $(OBJS)
clean:
rm -f $(OBJS)
With directories and files set up as per your example:
$ ls -R
.:
dirx diry dirz Makefile
./dirx:
a.cc
./diry:
b.cc
./dirz:
c.cc
it runs like:
$ make
g++ -c -o a_a.o dirx/a.cc
g++ -c -o b_b.o diry/b.cc
g++ -c -o c_c.o dirz/c.cc
Cribs: -
VPATH
foreach
basename
subst
.SECONDEXPANSION

Overwiting target directory in catch-all rule in GNU Makefile

Consider the following:
SRCS = somefile.c util/someother.c ../src/more.c
%.o : %.c
$(GCC) -MD -c $< -o $# -Wp,-MD,.deps/$*.d
#cp .deps/$*.d .deps/$*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < .deps/$*.d >> .deps/$*.P; \
rm -f .deps/$*.d
-include $(SRCS:%.c=.deps/%.P)
How would I change the above so that the .o files end up in ./? Currently they build in the directory the source file exists in and that's bad.
I'd do it this way:
SRCS = somefile.c someother.c more.c
%.o : %.c
[same as before]
-include $(SRCS:%.c=.deps/%.P)
vpath %.c util ../src

Resources