I'm trying to create a Linux image with Yocto project. I need the modbus library for C.
I added the libmodbus in IMAGE_INSTALL_append in the bitbake file of the image. Libmodbus is included in the meta-openembedded that I have.
Now I have a recipe to compile a simple c program that uses the modbus library (#include <modbus.h>). This program works in my host.
The bitbake file is the following:
SUMMARY = "modbustest Recipe"
LICENSE = "CLOSED"
SRC_URI = "file://test.c "
DEPENDS = "libmodbus"
S = "${WORKDIR}"
FILES_${PN} = "${libdir}/*.so"
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} test.c -o test -I/${D}/usr/lib/modbus/ -lmodbus
}
do_install_append() {
install -d ${D}/opt/modbustest/bin
install -m 0777 ${WORKDIR}/test ${D}/opt/modbustest/bin
}
FILES_${PN} = "/opt/modbustest/bin"
FILES_SOLIBSDEV = ""
INSANE_SKIP_${PN} = "dev-so"
When I create the image, this is the error:
ERROR: modbustest-0.1-r0 do_compile: Execution of '/home/uip/yocto-mx8/build-modbus/tmp/work/aarch64-ts-linux/modbustest/0.1-r0/temp/run.do_compile.3835' failed with exit code 1:
test.c:2:10: fatal error: modbus.h: No such file or directory
2 | #include <modbus.h>
| ^~~~~~~~~~
compilation terminated.
WARNING: exit code 1 from a shell command.
I know that library is to link to the compile but I don't know how to do.
Probably in the recipe file there are many errors. I copy and paste many solutions from internet but nothing works.
Does someone know how to solve it?
Thank you,
Marco
EDITED:
The accepted solution works for me but after I installed in the target board the library "libmodbus-dev" in place of "libmodbus". Finally, I modified the recipe with suggestion and now I can compile a C program that uses the modbus library.
CodePudding user response:
Problem:
modbus.h
is not found during do_compile (or any other header file for that matter)
Where is modbus.h?
modbus.h
as you mention you already know its coming from libmodbus, but for educational purposes lets say you didn't, to find where its coming from you can issue the following command:
$ oe-pkgdata-util find-path /usr/include/modbus/modbus.h
libmodbus-dev: /usr/include/modbus/modbus.h
Now, you definitely know its coming from libmodbus, the first step after this is to add it to DEPENDS
(you already have this, great).
Essentially what this does is that it will make everything that gets installed by libmodbus
available to your modbus test recipe
By this what happens is that bitbake creates hardlinks from the built artifacts from libmodbus and a "workspace" or "sandbox" directory where your test recipe is being built, it does this to avoid pollution from other packages, your test recipe will only have exactly what it needs to be built, nothing extra.
The key thing here is the location of such sandbox, all the dependencies for your recipe will be in ${WORKDIR}/recipe-sysroot
or ${WORKDIR}/recipe-sysroot-native
depending on each dependency, in your case it will be in ${WORKDIR}/recipe-sysroot
since you built libmodbus
for your target.
How to fix it:
Now the actual problem is you are manually invoking the compiler and passing your required include directories via -I
:
${CC} ${CFLAGS} ${LDFLAGS} test.c -o test -I/${D}/usr/lib/modbus/ -lmodbus
But, the include path you are passing is incorrect.
${D}
expands to ${WORKDIR}/image
, hence modbus.h
is not found because its not located anywhere in ${WORKDIR}/image/usr/lib/modbus
(you are also using a lib
in your include directory and thats also incorrect), the actual location of the file as mentioned above is in ${WORKDIR}/recipe-sysroot/usr/include/modbus/modbus.h
There is already a variable available for ${WORKDIR}/recipe-sysroot which you can use to simplify things:
${RECIPE_SYSROOT}
.
You also shouldnt really hardcode /usr
or /usr/lib
or /usr/include
there are variables available for those for portability ($prefix
, $libdir
$includedir
, etc).
TLDR:
When you invoke the compiler, instead of:
${CC} ${CFLAGS} ${LDFLAGS} test.c -o test -I/${D}/usr/lib/modbus/ -lmodbus
It should be:
${CC} ${CFLAGS} ${LDFLAGS} test.c -o test -I/${RECIPE_SYSROOT}/${includedir}/modbus/ -lmodbus