[CMake] order of includes seems wrong (or please help me understand)

Mario Emmenlauer mario at emmenlauer.de
Thu Jul 26 05:58:20 EDT 2018


Dear CMake users and developers,

I've just discovered a build problem that comes from a wrong order of
includes. I would know the correct order, but I am unable to instruct
CMake to use the order I need.

Here is a toy example that I tested with cmake 3.12.0:


----
cmake_minimum_required(VERSION 3.8)
project(MyLib VERSION 1.0.0)
find_package(XXX REQUIRED)
find_package(YYY REQUIRED)
add_library(${PROJECT_NAME} include/MyLib.hh src/MyLib.cc)
target_include_directories(${PROJECT_NAME}
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
        ${CMAKE_CURRENT_BINARY_DIR}
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
        ${XXX_INCLUDE_DIRS} ${YYY_INCLUDE_DIRS})
target_link_libraries(MyLib PUBLIC ${XXX_LIBRARIES} ${YYY_LIBRARIES})
# here come more commands for build flags etc.

enable_testing()
add_executable(MyTest test/src/MyTest.cc test/src/MyTest.hh)
target_include_directories(MyTest PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_SOURCE_DIR}/test/src
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_BINARY_DIR}
    ${GTEST_INCLUDE_DIRS})
target_link_libraries(MyTest PRIVATE MyLib ${GTEST_MAIN_LIBRARIES})
# here come more commands for build flags etc.
----


I configure cmake with -DCMAKE_PREFIX_PATH=${MY_PREFIX_PATH}. When
I build the project, the order of includes for MyLib is fine. But
for MyTest, the following are the first two includes:
   -IMyTest_autogen/include
   -I${MY_PREFIX_PATH}/include

I think the second include should come much later, only *after*
${CMAKE_CURRENT_SOURCE_DIR}/include, but it comes before. Therefore,
if older headers exists in ${MY_PREFIX_PATH}/include, they will be
used instead of ${CMAKE_CURRENT_SOURCE_DIR}/include!

I found that I can fix the problem by adding 'BEFORE' to all
target_include_directories(). However I'm puzzled why this helps.
Before anything I call target_include_directories(), and before other
includes I have ${CMAKE_CURRENT_SOURCE_DIR}/src,
${CMAKE_CURRENT_BINARY_DIR} and ${CMAKE_CURRENT_SOURCE_DIR}/include.
So what does 'BEFORE' mean in this case? Aren't these the first
includes any ways?

Thanks for any help, and Cheers,

    Mario Emmenlauer


--
BioDataAnalysis GmbH, Mario Emmenlauer      Tel. Buero: +49-89-74677203
Balanstr. 43                   mailto: memmenlauer * biodataanalysis.de
D-81669 München                          http://www.biodataanalysis.de/


More information about the CMake mailing list