Search code examples
yoctobitbake

Yocto Bitbake fails to find wrapper headers (include_next stind.h no such file)


I'm trying to create a bitbake recipe to build some source code that resides in a local folder (as opposed to fetching from a remote repo).

After running bitbake, I expect to have an executable file and a shared library in the resulting image.

The source code includes three CMakeLists.

So far, I'm able to:

  • Run cmake by itself to build the source code on my host and on the target (i.e. not using bitbake)
  • Using my .bb file, correctly point to the source code by using the variable OECMAKE_SOURCEPATH.
  • start running cmake using the default do_compile()

The build fails during do_compile() with the error:

In file included from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Inc/typedefs.h:29,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/DOIP/DOIP.h:32,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/ISOUDS/ISOUDS_MAIN/ISOUDS_Server_Cfg.h:30,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/ISOUDS/ISOUDS_ClearDiagInfo/ISOUDS_ClearDiagInfo_Cfg.c:25:
| /home/myname/project/nxp_s32/build_s32g274asbc2/tmp/work/aarch64-ms-linux/embitel-uds/1.0.0-r0/recipe-sysroot-native/usr/lib/aarch64-ms-linux/gcc/aarch64-ms-linux/10.2.0/include/stdint.h:9:16: fatal error: stdint.h: No such file or directory
|     9 | # include_next <stdint.h>
|       |                ^~~~~~~~~~
| compilation terminated.
| make[2]: *** [CMakeFiles/uds-server.dir/build.make:264: CMakeFiles/uds-server.dir/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/ISOUDS/ISOUDS_ClearDiagInfo/ISOUDS_ClearDiagInfo_Cfg.c.o] Error 1
| In file included from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Inc/typedefs.h:29,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/DOIP/DOIP.h:32,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/ISOUDS/ISOUDS_MAIN/ISOUDS_Server_Cfg.h:30,
|                  from /home/myname/UDS_Server_Integration/src/3rdparty/udsdoip/UDSSrvonDOIP/DoIPSrvProcess/Src/ISOUDS/ISOUDS_CntrlDTCSetting/ISOUDS_CntrlDTCSetting.c:13:
| /home/myname/project/nxp_s32/build_s32g274asbc2/tmp/work/aarch64-ms-linux/embitel-uds/1.0.0-r0/recipe-sysroot-native/usr/lib/aarch64-ms-linux/gcc/aarch64-ms-linux/10.2.0/include/stdint.h:9:16: fatal error: stdint.h: No such file or directory
|     9 | # include_next <stdint.h>
|       |                ^~~~~~~~~~

However, stdint.h does exist. I looked up what "include_next" is and it's a "wrapper header". I think GCC is using this to modify the headers for the target environment, i.e. this is a cross-compiler issue. I assume this would indicate that cmake is not configured correctly for cross-compilation, or not looking in the correct location for the modified headers.

I have never encountered this problem building other source code for the same target environment using the same cross-compiler. My .bb recipe is also written using the same variables as for other packages. I even compared the CMakeOutput.log and CMakeCache.txt for this failing recipe and other successful recipes and saw that most of the relevant variables were set with the same values.

This led me to believe this could be an issue with the CMakeLists.txt and not having configured cmake correctly for this particular source code.

I have tried adding -DCMAKE_NO_SYSTEM_FROM_IMPORTED=1 based on this thread. I have also avoided directly setting the cross-compiler based on this.

However, I'm at a loss for what I could be missing.

Other issues I've referenced: Referencing gcc with yocto recipe Makefile, unable to find stdint

Here are my CMakeLists for reference:

cmake_minimum_required(VERSION 3.13)

project("MyUDS"
    VERSION "1.0.0"
    LANGUAGES C)

include(GNUInstallDirs)

## --- C++ build flags ---
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_C_FLAGS "-MMD -MP -O4 -fcommon")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")

# Set version
set(PROJECT_VERSION_MAJOR 0 CACHE STRING "")
set(PROJECT_VERSION_MINOR 0 CACHE STRING "")
set(PROJECT_VERSION_PATCH 0 CACHE STRING "")
set(PROJECT_VERSION_BUILD 0 CACHE STRING "")

# changes binary and library outputs to ./build/bin and ./build/lib
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)

add_library(uds-server SHARED)

set_target_properties(uds-server PROPERTIES
    VERSION ${PROJECT_VERSION}
    SOVERSION ${PROJECT_VERSION_MAJOR})

add_subdirectory(src/3rdparty/udsdoip)

----- CMakeLists in src/3rdparty/udsdoip ------

file(GLOB_RECURSE sched_sources ${CMAKE_CURRENT_SOURCE_DIR}/UDSSrvonDOIP/DoIPSrvProcess/Sched/*.c)
add_executable(udsserver ${sched_sources})
target_link_libraries(udsserver uds-server pthread)
target_include_directories(
    udsserver
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/UDSSrvonDOIP/DoIPSrvProcess/Inc
            ${CMAKE_CURRENT_SOURCE_DIR}/UDSSrvonDOIP/DoIPSrvProcess/Sched/Inc
            ...
            ${CMAKE_CURRENT_SOURCE_DIR}/UDSSrvonDOIP/DoIPSrvProcess/Src/Inc
)

add_subdirectory(UDSSrvonDOIP/DoIPSrvProcess)

install(TARGETS udsserver DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/service/uds_server.sh DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/service/uds_server.service
        DESTINATION /etc/systemd/system
)

----- CMakeLists in UDSSrvonDOIP/DoIPSrvProcess ------

project(lib-uds-server)

# Enable helper debugging messages
target_compile_definitions(
    uds-server PUBLIC DEBUG_SOCKCOMM DOIP_SERVER_PRINT_TCP_RX_PACKET_DATA DOIP_SERVER_PRINT_FOUND_NET_DEVS
)

file(GLOB_RECURSE isouds_sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)

target_sources(uds-server PRIVATE ${isouds_sources})

target_include_directories(
    uds-server
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Inc
            ${CMAKE_CURRENT_SOURCE_DIR}/Sched
            ${CMAKE_CURRENT_SOURCE_DIR}/Sched/Inc
            ...
            ${CMAKE_CURRENT_SOURCE_DIR}/Src/ISOUDS/ISOUDSSecurDtaTrans
)

install(TARGETS uds-server
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

Solution

  • Found the issue, and it's a bit of a dumb mistake.

    I was not inheriting the CMake C flags set by Yocto that are needed for the cross-compile environment. So no matter what flags I added in my .bb recipe file, they were being overridden in the source code CMakeLists.txt.

    Here, where I was setting the C flags, I was not inheriting Yocto's flags.

    set(CMAKE_C_FLAGS "-MMD -MP -O4 -fcommon")
    

    I should have used the existing flags and appended the ones specific to my source code like this:

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MMD -MP -O4 -fcommon")
    

    This got my build working.