简体   繁体   中英

Yocto: "modbus.h" no such file or directory

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 inte.net 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.

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

Longer explanation:

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).

The correct path you should be using is:

${RECIPE_SYSROOT}/${includedir}/modbus/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM