Driver is not compiling "No rule to make target" - makefile

Compile this driver with:
echo "obj-m := tiny_i2c_adap.o" > Makefile
make -C SUBDIRS=$PWD modules
Makefile:
obj-m := tiny_i2c_adap.o
Error :
prashanth#prashanth-Lenovo-ideapad-520-15IKB:~$ make -C /usr/src/linux-headers-$(uname -r) M=$PWD modules
make: Entering directory '/usr/src/linux-headers-5.1.7-050107-generic'
make[1]: * No rule to make target '/home/prashanth/tiny_i2c_adap.c', needed by '/home/prashanth/tiny_i2c_adap.o'. Stop.
Makefile:1571: recipe for target 'module/home/prashanth' failed
make: * [module/home/prashanth] Error 2
make: Leaving directory '/usr/src/linux-headers-5.1.7-050107-generic'

Remember $PWD is a shell variable, which contains the current working directory. So when you run:
~$ make -C /usr/src/linux-headers-$(uname -r) M=$PWD modules
the value of $PWD here is the directory you are in when you run make (in this case your home directory) so you're running:
~$ make -C /usr/src/linux-headers-$(uname -r) M=/home/prashanth modules
So the kernel makefile assumes that your module lives in /home/prashanth because that's where you set the M variable to.
You need to either use the correct path for M, or else use cd to switch to the directory containing your source before invoking make so that $PWD will contain the right path.

Related

Does GNU make prepend a "./" to the path of included makefiles?

Running GNU Make 4.4 on Windows 10.
I'm trying to include a generated makefile from another. When the included file is given as an absolute directory, I get the following error:
makefile:6: ./D:/Users/xxxxxxxx/Workspace/test/make/makefile-deps.mk: Invalid argument
make: *** No rule to make target './D:/Users/xxxxxxxx/Workspace/test/make/makefile-deps.mk'. Stop.
Here is a makefile which re-creates the problem:
OUTPUT_DIR := $(abspath .)
DEPS_FILE := $(OUTPUT_DIR)/makefile-deps.mk
include $(DEPS_FILE)
CSRCS := a.c b.c c.c d.c
$(DEPS_FILE): $(CSRCS) $(OUTPUT_DIR)
#echo MAKEDEPS
#$(MAKEDEPS) --output-file $# $(CSRCS)
show:
#echo DEPS_FILE=$(DEPS_FILE)
If I comment out the include line, the show target shows that the directory is not prepended:
─▶ make show
DEPS_FILE=D:/Users/xxxxxxxx/Workspace/test/make/makefile-deps.mk
So it must be the include directive prepending the ./ to the path name, causing the failure. Does any know a work-around for this?

Kernel module build fails with "missing argument to -gdwarf-"

I am trying to build a Xilinx XDMA driver for Yocto, using their supplied makefile. When I run my recipe the build fails with the following errors:
DEBUG: Executing shell function do_compile
NOTE: make -j 32 KERNEL_SRC=./tmp/work-shared/intel-corei7-64/kernel-source
KERNEL_PATH=./tmp/work-shared/intel-corei7-64/kernel-source
KERNEL_VERSION=5.10.78-intel-pk-standard CC=x86_64-poky-linux-gcc
-fuse-ld=bfd
-fmacro-prefix-map=./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0=/usr/src/debug/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0
-fdebug-prefix-map=./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0=/usr/src/debug/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0
-fdebug-prefix-map=./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/recipe-sysroot=
-fdebug-prefix-map=./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/recipe-sysroot-native=
-fdebug-prefix-map=./tmp/work-shared/intel-corei7-64/kernel-source=/usr/src/kernel LD=x86_64-poky-linux-ld.bfd
AR=x86_64-poky-linux-ar
O=./tmp/work-shared/intel-corei7-64/kernel-build-artifacts KBUILD_EXTRA_SYMBOLS=
Makefile:17: XVC_FLAGS: .
make -C /lib/modules/5.13.0-40-generic/build
M=./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma modules
make[1]: Entering directory '/usr/src/linux-headers-5.13.0-40-generic'
make[2]: Entering directory './tmp/work-shared/intel-corei7-64/kernel-build-artifacts'
./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma/Makefile:17: XVC_FLAGS: .
CC [M] ./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma/libxdma.o
CC [M] ./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma/xdma_cdev.o
x86_64-poky-linux-gcc: error: missing argument to '-gdwarf-'
CC [M] ./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma/cdev_ctrl.o
make[3]: *** [/usr/src/linux-headers-5.13.0-40-generic/scripts/Makefile.build:281: ./tmp/work/intel_corei7_64-poky-linux/xdma-driver-mod/1.0+gitAUTOINC+8d75946900-r0/git/linux_driver/xdma/libxdma.o] Error 1
make[3]: *** Waiting for unfinished jobs....
x86_64-poky-linux-gcc: error: missing argument to '-gdwarf-'
ERROR: oe_runmake failed
WARNING: exit code 1 from a shell command.
I have no idea why this happens as it is not something I have specifically enabled. I have searched through the module.bbclass file but I couldn't see anything obvious. I believe that something needs to be configured such that the -gdwarf- actual ends up being set to a valid value (e.g. -gdwarf-2 or -gdwarf-4 etc.)
A grep through the poky repo for dwarf did not reveal anything neither did a search of /usr/src/linux-headers-5.13.0-40-generic/scripts/.
My bitbake recipe is as follows:
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=441c1ecbc199a036abf37f3aa47c5f34"
SRC_URI += https://github.com/Xilinx/dma_ip_drivers.git;protocol=ssh;nobranch=1;branch=master"
# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "8d7594690058dfa828accc02ac81348e416ffe38"
S = "${WORKDIR}/git/xdma/linux-driver/xdma"
RPROVIDES_${PN} += "xdma"
inherit module
EXTRA_OEMAKE_task-install:append = " -C ${STAGING_KERNEL_DIR} M=${S}"
EXTRA_OEMAKE += "KDIR=${STAGING_KERNEL_DIR}"
The makefile is the standard one from GitHub. The driver builds correctly for Ubuntu using make and I can also build the module if I change my recipe such that it does not include inherit module; this change will build the module (xdma.ko) but does to install it in the roofs. I am also not sure if inherit module includes additional functionality which may be rewired.
How to I either:
prevent / disable the -gdwarf flag being generated
configure the recipe that the -gdwarf- resolves to something valid
View the actual command being invoked that is causing the issue.
Attempts to build the xdma.ko module without the inherit module result in an invalid binary being built, i.e. when I try an load the module on the target I get:
insmod xdma.ko
insmod: ERROR: could not insert module xdma.ko: Invalid module format
Which indicates that the module is compiled from the wrong target.
inherit module is required when building kernel modules for Yocto. If it is omitted the build modules is not compatible with the target.
Workaround for the -gdwarf- error was to manually write a new makefile which is compatible with Yocto:
TARGET_MODULE:=xdma
topdir := $(shell cd $(src)/.. && pwd)
EXTRA_CFLAGS := -I$(topdir)/include
SRC := $(shell pwd)
$(TARGET_MODULE)-objs := libxdma.o xdma_cdev.o cdev_ctrl.o cdev_events.o cdev_sgdma.o cdev_xvc.o cdev_bypass.o xdma_mod.o xdma_thread.o
obj-m := $(TARGET_MODULE).o
all :
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
This makefile correctly builds the Xilinx XDMA driver for Yocto. I can confirm that the driver works with Kintex-KC705 FPGA development card.

Ensure that make is invoked from a specific directory

I would like all my recipes to be executed from a specific directory, the directory where the Makefile is located.
This is the default behaviour when invoking make without options, but an user could always run :
(cd /somewhere; make -f /path/to/directory/Makefile)
To ensure that make working directory is the same as the directory where the Makefile is located, there are multiple solutions :
run make without options (default), from this specific directory (cd /path/to/directory; make)
use make -C /path/to/directory
cd to /path/to/directory for each recipe, like this :
MAKEFILE_DIR_LOCATION := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
a:
cd ${MAKEFILE_DIR_LOCATION} && do_something_from_makefile_folder
b:
cd ${MAKEFILE_DIR_LOCATION} && do_another_thing_from_makefile_folder
The problem is that the first two solutions requires actions from the user invoking the Makefile, while the last one clutters the Makefile.
Is there a prettier way to ensure that all recipes are executed from the directory where the Makefile is located?
Extra solution (does not work)
I also thought comparing the working directory ($(shell pwd)) to ${MAKEFILE_DIR_LOCATION}, and exit if it does not match (at least to warn the user that make is not correctly invoked), but I can't find how to do this. I tried :
MAKEFILE_DIR_LOCATION := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
WORKING_DIR := $(shell pwd)
ifneq (${MAKEFILE_DIR_LOCATION}, ${WORKING_DIR})
#error "Please run make from the directory of the Makefile, or use make -C"
endif
a:
do_something_from_makefile_folder
b:
do_another_thing_from_makefile_folder
But I got a missing separator error (line #error), or a recipe commences before first target if #error line is indented.
Answering the question you asked without commenting on whether it's a good idea or not, I'm not sure where you found this syntax:
#error "Please run make from the directory of the Makefile, or use make -C"
but it's definitely wrong. error is a make function, so you want this:
$(error Please run make from the directory of the Makefile, or use make -C)
A variant on your last attempt would re-invoke Make in the correct directory, with the same target:
ifneq (${MAKEFILE_DIR_LOCATION},${WORKING_DIR})
%:
$(MAKE) -C ${MAKEFILE_DIR_LOCATION} $#
.PHONY: %
else
## rest of Makefile rules
endif

Specifying different GNUmakefile for GNU make command

I have two GNUmakefiles in my directory as follows,
GNUmakefile &
GNUmakefile2
Could someone please let me know the command I have to use, if I have to let the "make" command to process "GNUmakefile2" instead of "GNUmakefile".
I used the below command,
make -f GNUmakefile2
but in that case, I am getting the following errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: ** No rule to make target `internal-master-tool-all'. Stop.*
make: ** [internal-all] Error 2*
I think it is considering GNUmakefile as makefile (when I use make with -f command), so it is checking for rules in GNUmakefile.
At present what I am doing is I am renaming the required file (which I want, make command to execute) to "GNUmakefile". And I am not getting any errors while executing "make" command, but I don't think this is the correct solution.
Please let me know which command I need to use for this scenario. Thanks for your help.
After checking Beta's solution (i.e.,but that makefile is invoking Make a second time, and the second Make process is probably reading GNUmakefile) what I have done is I renamed existing "GNUmakefile" to "GNUmakefile3".
So at present in my directory the following makefiles are present:- "GNUmakefile2" & "GNUmakefile3".
And then I executed the following command:- $ make -f GNUmakefile2
I recieved the below errors,
This is gnustep-make 2.6.1. Type 'make print-gnustep-make-help' for help.
make[1]: GNUmakefile: No such file or directory
make[1]: * No rule to make target `GNUmakefile'. Stop.
make: * [internal-all] Error 2
Please let me know what is the problem here
Your makefile includes two huge makefiles from the FSF. The second, library.make, contains this rule:
ifeq ($(GNUSTEP_MAKE_PARALLEL_BUILDING), no)
# Standard building
...
else
# Parallel building. ...
internal-library-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) $(OBJ_DIRS_TO_CREATE)
$(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) ...
endif
and the first, common.make contains this assignment:
# The default name of the makefile to be used in recursive invocations of make
ifeq ($(MAKEFILE_NAME),)
MAKEFILE_NAME = GNUmakefile
endif
So try either make -f GNUmakefile2 GNUSTEP_MAKE_PARALLEL_BUILDING=no or make -f GNUmakefile2 MAKEFILE_NAME=GNUmakefile2, and see if that solves the problem.

Makefile.am - Manual target prerequisite + addprefix?

I have a autotool project where part of the source code is downloaded dynamically from the net (because of IP rights preventing direct redistribution) and then built.
I have a Makefile.am that works but I'm not happy about some of it's aspects.
Here it is:
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS = -fPIC -Wall ${SYMBOL_VISIBILITY}
LIBVERSION=0:0:0
REFSRC_PATH=refsrc
REFSRC_SRC=refsrc/dtx.c refsrc/globdefs.c refsrc/host.c refsrc/mathhalf.c refsrc/sp_enc.c refsrc/sp_rom.c refsrc/vad.c refsrc/err_conc.c refsrc/homing.c refsrc/mathdp31.c refsrc/sp_dec.c refsrc/sp_frm.c refsrc/sp_sfrm.c
${REFSRC_PATH}/.downloaded:
./fetch_sources.py "${REFSRC_PATH}"
for f in `ls -1 "${REFSRC_PATH}"/*.{c,h}`; do \
sed -i -e"s/round/round_l2s/" "$$f"; \
done
touch $#
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
lib_LTLIBRARIES = libgsmhr.la
libgsmhr_la_SOURCES = libgsmhr.c $(REFSRC_SRC)
clean-local:
-rm -rf ${REFSRC_PATH}
So essentially, libgsmhr.c is my main wrapper, then I download the source code in a refsrc/ subdirectory and patch it a little.
First problem is that in REFSRC_SRC I would have loved to use a $(addprefix ...) instead of repeating refsrc/ in front of each .c file. But that doesn't seem to work and autoreconf complains a little.
Failure details (when removing the refsrc/ prefix from REFSRC_SRC= and using $(addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}) on the dependency list):
bash$ autoreconf -i
libgsmhr/Makefile.am:19: addprefix ${REFSRC_PATH}/, ${REFSRC_SRC}: non-POSIX variable name
libgsmhr/Makefile.am:19: (probably a GNU make extension)
(configure works fine)
bash$ make
...
make[2]: Entering directory `/tmp/ram/gapk.build/libgsmhr'
CC libgsmhr.lo
CCLD libgsmhr.la
make[2]: Leaving directory `/tmp/ram/gapk.build/libgsmhr'
...
(So as you see it didn't include any of the downloaded .c files, didn't even download them at all. The compile works because libgsmhr.c is a stub that doesn't use the symbols in those file yet)
Second problem is this rule:
${REFSRC_PATH}/dtx.c: ${REFSRC_PATH}/.downloaded
I have to explicitely list the first file (dtx.c) instead of using a wildcard like:
${REFSRC_PATH}/%.c: ${REFSRC_PATH}/.downloaded
If I try to use the wildcard, then autoreconf complains and also it just doesn't work ... (pattern doesn't match somehow).
Failure detail:
bash$ autoreconf -i
libgsmhr/Makefile.am:16: `%'-style pattern rules are a GNU make extension
(configure works fine)
bash$ make
...
make[2]: *** No rule to make target `refsrc/dtx.c', needed by `dtx.lo'. Stop.
...
Sylvain
You seem to be writing a makefile in GNUMake style, but actually running some other version of Make. If it's not obvious what autoreconf is calling, you could insert a rule in the makefile:
dummy:
#echo using $(MAKE)
$(MAKE) -v
If this theory proves correct, you can either persuade autoconf to use GNUMake, or write for the version it's using.

Resources