MantisBT - CMake
View Issue Details
0008761CMakeCMakepublic2009-03-18 19:362010-08-31 18:10
Alex Neundorf 
Brad King 
normalmajoralways
closedwon't fix 
CMake-2-6 
CMake 2.8.3 
0008761: TRY_COMPILE() doesn't handle imported library targets in CMAKE_REQUIRED_LIBRARIES
With cmake 2.6 you can export targets and import them later again. If you do this for targets which are shared libraries, you can use these imported targets to link against them.
In KDE e.g. the shared library kdeui (-> libkdeui.so) is exported with the namepace "KDE4__" as KDE4__kdeui.
Now when importing this target other targets can be linked against this target and everything works fine.
A problem appears when somebody tries to do a try_compile() or try_run() via check_cxx_source_compiles/runs() with a source file which needs this library. If he sets CMAKE_REQUIRED_LIBRARIES to KDE4__kdeui, then the created project doesn't know that KDE4__kdeui is an imported target and instead just tries to link against this library, i.e. it adds a -lKDE4__kdeui to the link command, which will obviously fail.
Here's the thread on the kde-buildsystem list:
http://lists.kde.org/?t=123686453500002&r=1&w=2 [^]

Maybe TRY_COMPILE() shoudl process CMAKE_REQUIRED_LIBRARIES and deal with imported library targets appropriately ?

Alex
No tags attached.
Issue History
2009-03-18 19:36Alex NeundorfNew Issue
2009-03-18 19:36Alex NeundorfStatusnew => assigned
2009-03-18 19:36Alex NeundorfAssigned To => Brad King
2009-10-06 13:40Alex NeundorfNote Added: 0017978
2009-10-06 13:57Brad KingNote Added: 0017979
2009-10-06 14:07Alex NeundorfNote Added: 0017980
2009-10-06 14:31Brad KingNote Added: 0017989
2009-10-06 14:35Alex NeundorfNote Added: 0017991
2009-10-06 15:39Brad KingNote Added: 0017995
2009-10-06 15:40Brad KingNote Edited: 0017995
2010-07-27 15:51Brad KingNote Added: 0021500
2010-07-27 15:51Brad KingStatusassigned => closed
2010-07-27 15:51Brad KingResolutionopen => won't fix
2010-08-31 18:10David ColeTarget Version => CMake 2.8.3

Notes
(0017978)
Alex Neundorf   
2009-10-06 13:40   
I'm not sure, didn't you fix that one already some time ago ?

Alex
(0017979)
Brad King   
2009-10-06 13:57   
No, this may be REALLY hard to fix. The targets are loaded by script code executed in the context of the main project. There is no good way to send information about imported targets to the try-compiled projects. The try_compile() command doesn't know anything about CMAKE_REQUIRED_LIBRARIES. That is an API specified by the check macros (to approximate optional arguments).

If a try-compiled project wants to link to a target imported into the main project, the test project should probably import the target too. Getting this to work with check_cxx_source_compiles/runs() will require adding arguments to specify custom setup .cmake scripts that can do things like import targets.

Another approach that comes to mind is to teach the macros that use CMAKE_REQUIRED_LIBRARIES to loop over the list and get the LOCATION_<CONFIG> property from any target that is imported, where <CONFIG> is the configuration to be built in the test project.
(0017980)
Alex Neundorf   
2009-10-06 14:07   
I implemented something similar for KDE, see the files CheckCXXSourceCompiles.cmake, CheckCXXSourceRuns.cmake and HandleImportedTargetsInCMakeRequiredLibraries.cmake in kdelibs/cmake/modules/:
http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ [^]

Alex
(0017989)
Brad King   
2009-10-06 14:31   
So, those are the current version of these macros:

  http://lists.kde.org/?l=kde-buildsystem&m=123689449526711 [^]

The original use case is this:

  Checking if the QtScript Qt Bindings are installed.
  http://lists.kde.org/?l=kde-buildsystem&m=123688778516276 [^]

I think this is too specific to expect a generic check_cxx_source_runs to handle, since that is meant for small code fragments to avoid having to construct a whole source or whole project. It looks to me like the try-compiled project itself should import KDE so that it can link against kdeui. The outer try_compile call can easily pass the kde dir so that find_package(KDE) in the test project does not need to search.
(0017991)
Alex Neundorf   
2009-10-06 14:35   
Hmm, I don't understand.
The issue is, before KDE used imported targets using ${KDE4_KDECORE_LIBS} for CMAKE_REQUIRED_LIBRARIES worked, with imported targets it didn't anymore.
The script above does something similar to what you described I think, and it makes this work again.
I don't think the test-project should have to do a find_package(KDE4) if the kde libs and include dirs are already known.

Alex
(0017995)
Brad King   
2009-10-06 15:39   
(edited on: 2009-10-06 15:40)
I understand the need for source compatibility in KDE, so feel free to leave those macros. I don't think such complexity is worthwhile for CMake in general though.

Using this KDE case as an example, but ignoring the need for compatibility, the following is how I see a general CMake user solving this problem. The purpose of the test is to ask "Can a project that uses KDE use feature X?". There are two ways to answer this question:

  (1) KDE should have installed a file that says whether feature X is available.
      The information should already be available through the KDE4 config file.

  (2) Build a test project that uses KDE and tries feature X.

The best way to implement (2) is to construct a project that uses KDE. The way a project uses KDE is to do find_package(KDE4) and then use it. The try_compile() invocation can save the test project some work by giving it the location of KDE so that the find_package() command does not actually have to search. It will still load the results.

Anything short of a test project that does find_package() is only "a project that approximately uses KDE based on macro-based link interface computation". Such a project is not representative of the main project's case, since the main project does find_package(KDE4).

(0021500)
Brad King   
2010-07-27 15:51   
I just read through my previous comments on this. There is no way we will support this in CMake. Comment 17979 explains why it does not make sense to support in general, and 17995 describes a better solution.