I've come across an odd situation where I'm unsure what the most portable and recommended solution would be.

I'm linking a program against the CURL and ICU libraries. CURL has traditional variables for the includes and libraries; ICU has imported targets.

In FindICU:
          set_target_properties(${_ICU_imported_target} PROPERTIES
            INTERFACE_INCLUDE_DIRECTORIES "${ICU_INCLUDE_DIR}")

In my code:

find_package(CURL)
find_package(ICU COMPONENTS uc data)
[...]
list(APPEND libxerces_c_DEPS ${CURL_LIBRARIES})
include_directories(${CURL_INCLUDE_DIRS})
list(APPEND libxerces_c_DEPS ICU::uc ICU::data)

And the resulting includes on the compiler invocation:

/usr/bin/CC -DHAVE_CONFIG_H -D_FILE_OFFSET_BITS=64 -I. -I/tmp/b2/xerces-source/src -Isrc -I/tmp/b2/xerces-source/tests -isystem /tmp/b2/superbuild-install/include -msse2 -MD -MT tests/CMakeFiles/XSValueTest.dir/src/XSValueTest/XSValueTest.cpp.o -MF tests/CMakeFiles/XSValueTest.dir/src/XSValueTest/XSValueTest.cpp.o.d -o tests/CMakeFiles/XSValueTest.dir/src/XSValueTest/XSValueTest.cpp.o -c /tmp/b2/xerces-source/tests/src/XSValueTest/XSValueTest.cpp

The problem is this:
CURL is in /usr/local/include
ICU v55 is in /usr/local/include
ICU v57 is in /tmp/b2/superbuild-install/include with its libs in /tmp/b2/superbuild-install/lib

CMAKE_PREFIX_PATH is set appropriately, and all the Find module checks are correct. The problem is that the ICU INTERFACE_INCLUDE_DIRECTORIES is treated as a system include. This would be OK, if it were not for the fact that the CURL includes are placed before it.

The problem is that it's not a system path. However, the CURL path *is*. And this leads to it building against the ICU55 headers, and then failing to link against the ICU57 libraries. But that's just the situation on this specific (FreeBSD) system; the situation could be reversed on another with a locally built CURL and a system ICU and CURL.

I see that I could use NO_SYSTEM_FROM_IMPORTED for the imported target, and/or use BEFORE|AFTER SYSTEM with [target_]include_directories. However, none of these feel appropriate. They would require knowledge I don't have as the cmake script author--either of these libraries could be using system or non-system paths; I don't have the foreknowledge to make that determination.

How could an end user override what are system paths and what are not without hand-editing the script?

It seems (being naive) that the hardcoded behaviour of treating INTERFACE_INCLUDE_DIRECTORIES as system includes isn't a universally useful default, and while I can override the behaviour, that's a explicit action on the part of the script author, and might be inappropriate for the user's system. Whether a path is a system include or not seems to be something the end user should be able to tune, since the script author and cmake find module authors have no idea what the local situation is for any arbitrary system. For example, it wouldn't hurt for cmake to "know" that /usr/local/include is a system path as a built-in default, and allow additional paths to be added, and then if a random find module adds it such that it's used by a target as a non-system include we know we can ignore it and just use it as a system include instead. Unless I'm misunderstanding the situation and making this work is already possible.


Thanks,
Roger
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to