I’m finding the LibXml2 package and would appreciate insights in what I’m doing wrong. CMake 3.22 on Ubuntu 22.04.5.
The CMakeLists.txt file contains the snippet:
find_package(LibXml2)
if (LibXml2_FOUND)
#target_include_directories(${LIBRARY} PRIVATE ${LIBXML2_INCLUDE_DIRS})
#target_link_libraries(${LIBRARY} PRIVATE ${LIBXML2_LIBRARIES})
target_link_libraries(${LIBRARY} PRIVATE LibXml2::LibXml2)
endif()
Building on Linux works fine. The problem is when cross-compiling for QNX where flags are somehow unexpected injected for the ${LIBRARY} target that causes the system include path to be broken.
Specifically, I looked at the file in my local project called tools/cpuid-x86/libcpuid/src/CMakeFiles/libcpuid.dir/flags.make and it contains (split on lines to make it readable):
CXX_INCLUDES =
-I/home/jcurl/source/code.research/qnx/lib/libubench/include
-I/home/jcurl/source/code.research/qnx/lib/libstdext/include
-I/home/jcurl/source/code.research/qnx/lib/libosqnx/include
-I/home/jcurl/source/code.research/qnx/tools/cpuid-x86/libcpuid/src/../include
-I/home/jcurl/source/code.research/qnx/build/qnx8-n/tools/cpuid-x86/libcpuid/src
-Wp,-isystem,/home/jcurl/qnx/qnx800/target/qnx/usr/include
Removing the last line manually allows the build to succeed.
What is causing CMake to inject -Wp,-isystem,/home/jcurl/qnx/qnx800/target/qnx/usr/include and how do I get rid of it?
If I modify the CMakeLists.txt file to use ${LIBXML2_INCLUDE_DIRS} and ${LIBXML2_LIBRARIES} instead, I get a working build.
CXX_INCLUDES =
-I/home/jcurl/source/code.research/qnx/lib/libubench/include
-I/home/jcurl/source/code.research/qnx/lib/libstdext/include
-I/home/jcurl/source/code.research/qnx/lib/libosqnx/include
-I/home/jcurl/source/code.research/qnx/tools/cpuid-x86/libcpuid/src/../include
-I/home/jcurl/qnx/qnx800/target/qnx/usr/include
-I/home/jcurl/source/code.research/qnx/build/qnx8-w/tools/cpuid-x86/libcpuid/src
For information, I’m cross compiling on QNX, and my target file looks like:
set(CMAKE_SYSTEM_NAME QNX)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(arch gcc_ntox86_64)
set(CMAKE_C_COMPILER qcc)
set(CMAKE_C_COMPILER_TARGET ${arch})
set(CMAKE_CXX_COMPILER q++)
set(CMAKE_CXX_COMPILER_TARGET ${arch})
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(LIBXML2_LIBRARY "$ENV{QNX_TARGET}/x86_64/usr/lib/libxml2.so" CACHE FILEPATH "")
set(LIBXML2_INCLUDE_DIR "$ENV{QNX_TARGET}/usr/include" CACHE PATH "")
Note, I have to set it to the cache, because otherwise it would fail on a second find_package(LibXml2) call.
When I reviewed the code in /usr/share/cmake-3.22/Modules/FindLibXml2.cmake, I don’t really see where this is coming in, except it’s using INTERFACE instead of PRIVATE.
if(LibXml2_FOUND AND NOT TARGET LibXml2::LibXml2)
add_library(LibXml2::LibXml2 UNKNOWN IMPORTED)
set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIRS}")
set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXML2_DEFINITIONS}")
set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_LOCATION "${LIBXML2_LIBRARY}")
endif()
Showing that it may not be that difference, I include using INTERFACE instead of PRIVATE:
target_include_directories(${LIBRARY} INTERFACE ${LIBXML2_INCLUDE_DIRS})
target_link_libraries(${LIBRARY} INTERFACE ${LIBXML2_LIBRARIES})
and the build still works.