[CMake] Trouble with conditional generator expression inside target_link_libraries

Björn Blissing bjorn.blissing at vti.se
Thu Oct 4 13:09:32 EDT 2018


Hi Marc,

If that is the case that mixing of “optimized” and “debug” keywords with generator expressions is impossible, I think this should be mentioned in the official documentation. It took us the better part of an afternoon to track down why we suddenly had a dependency to a library called “optimized.lib”.

Other people seem to struggle with similar issues as well:
https://www.google.com/search?q=optimized.lib+cmake

Regards,
Björn


From: Marc CHEVRIER <marc.chevrier at gmail.com>
Sent: Thursday, October 4, 2018 6:59 PM
To: Björn Blissing <bjorn.blissing at vti.se>
Cc: Andrew Fuller <afuller at teradici.com>; Eric Noulard <eric.noulard at gmail.com>; CMake Mailinglist <cmake at cmake.org>
Subject: Re: [CMake] Trouble with conditional generator expression inside target_link_libraries

I am afraid that you cannot mix "optimized" or "debug" keywords with "generator expressions" because keywords handling is done during evaluation of command "target_link_libraries" and "generator expressions" are evaluated during generation.

And target_link_libraries expect following pattern: [<keyword>] <library> [<library> ...], so specifying a generator expression wrapping this breaks the parsing of the arguments: keyword is no longer at the beginning of the sequence so it is no longer  recognized as is...

So, The most efficient way to work-around this problem is to transform your list of libraries in valid generator expressions:

  *   INITIAL: optimized foo debug food_d
  *   RESULT: $<$<CONFIG:RELEASE>:foo> $<$<CONFIG:DEBUG>:foo_d>
For that purpose, an helper function can do the trick...

Le jeu. 4 oct. 2018 à 18:34, Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>> a écrit :
Hi Andrew,

That works, but as previously said. The third party find module I am using do not differentiate between debug and release libraries. To make matters even worse the keywords “optimized” and “debug” is already in the variable list, trying to split them will be painful.

The workaround I am using right now is to have an IF-statement for the list option:

if(${USE_FOOLIB})
    target_link_libraries(my_exe
    PUBLIC
        ${FOO_LIBRARIES}
    )
endif()


target_link_libraries(my_exe
    PUBLIC
         $<$<BOOL:${USE_BARLIB}>:bar>
)

But that breaks the pattern with using generator expressions, as I do for the rest of my options.

I don’t know if this should be considered a bug, but it seems really strange that generator expressions should break down for only this special case, i.e. the combination using lists with the conditional operator BOOL and using it inside target_link_libraries.

I don’t know if other CMake functions will react similarly bad to the list/bool operator combo.

Regards,
Björn


From: Andrew Fuller <afuller at teradici.com<mailto:afuller at teradici.com>>
Sent: Thursday, October 4, 2018 6:16 PM

To: Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>>; Eric Noulard <eric.noulard at gmail.com<mailto:eric.noulard at gmail.com>>
Cc: CMake Mailinglist <cmake at cmake.org<mailto:cmake at cmake.org>>
Subject: Re: [CMake] Trouble with conditional generator expression inside target_link_libraries


What about this:



list(APPEND FOO_LIBRARIES_OPT foo)
list(APPEND FOO_LIBRARIES_DBG foo_d)

target_link_libraries(my_exe
   PUBLIC
        debug "$<$<BOOL:${USE_FOOLIB}>:${FOO_LIBRARIES_DBG}>"
        optimized "$<$<BOOL:${USE_FOOLIB}>:${FOO_LIBRARIES_OPT}>"
        "$<$<BOOL:${USE_BARLIB}>:bar>"
)

A little more verbose.

________________________________
From: Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>>
Sent: October 4, 2018 9:00:28 AM
To: Andrew Fuller; Eric Noulard
Cc: CMake Mailinglist
Subject: RE: [CMake] Trouble with conditional generator expression inside target_link_libraries


Hi Andrew,



When I put the genex inside double quotes I get:

optimized.lib;foo.lib;debug.lib;foo_d.lib;bar.lib; --- for both debug and release builds

Regards,

Björn





From: Andrew Fuller <afuller at teradici.com<mailto:afuller at teradici.com>>
Sent: Thursday, October 4, 2018 5:54 PM
To: Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>>; Eric Noulard <eric.noulard at gmail.com<mailto:eric.noulard at gmail.com>>
Cc: CMake Mailinglist <cmake at cmake.org<mailto:cmake at cmake.org>>
Subject: Re: [CMake] Trouble with conditional generator expression inside target_link_libraries



What happens if you put the genex inside double quotes?



target_link_libraries(my_exe

    PUBLIC

         "$<$<BOOL:${USE_FOOLIB}>:${FOO_LIBRARIES}>"

         "$<$<BOOL:${USE_BARLIB}>:bar>"

)



________________________________

From: CMake <cmake-bounces at cmake.org<mailto:cmake-bounces at cmake.org>> on behalf of Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>>
Sent: October 4, 2018 8:49:19 AM
To: Eric Noulard
Cc: CMake Mailinglist
Subject: Re: [CMake] Trouble with conditional generator expression inside target_link_libraries



Hi Eric,



I tried to do a self contained minimal example:



cmake_minimum_required(VERSION 3.12)

project(expension_error LANGUAGES CXX)



add_executable(my_exe main.cpp)



option(USE_FOOLIB "Use foo.lib" ON)

option(USE_BARLIB "Use bar.lib" ON)



list(APPEND FOO_LIBRARIES optimized foo)

list(APPEND FOO_LIBRARIES debug foo_d)





target_link_libraries(my_exe

    PUBLIC

         $<$<BOOL:${USE_FOOLIB}>:${FOO_LIBRARIES}>

         $<$<BOOL:${USE_BARLIB}>:bar>

)



But when I run this script using CMake 3.12.2, it expands to something even worse:



$<1:optimized;foo.lib;foo_d>.lib;bar.lib --- for debug builds

$<1:optimized;foo.lib;>.lib;bar.lib-- for release builds



So something goes really wrong when I try to use a list inside a conditional generator expression inside target_link_libraries().



Regards,

Björn







From: Eric Noulard <eric.noulard at gmail.com<mailto:eric.noulard at gmail.com>>
Sent: Thursday, October 4, 2018 5:10 PM
To: Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>>
Cc: CMake Mailinglist <cmake at cmake.org<mailto:cmake at cmake.org>>
Subject: Re: [CMake] Trouble with conditional generator expression inside target_link_libraries





Le jeu. 4 oct. 2018 à 16:53, Björn Blissing <bjorn.blissing at vti.se<mailto:bjorn.blissing at vti.se>> a écrit :

Hello Eric,



The minimal example was just to display the expansion error. In real life the code uses a Boolean variable (and the rest of the CMake code is much larger as well).

It was just to show the expansion error you get if you try to use a conditional generator expression inside a target_link_libraries function.



Sometimes the devil is hiding in the details.

Do ou manage to reproduce the genex expansion error on a toy example?



I do agree that using it would be simpler if I could use:

     $<$<CONFIG:Debug>:${MYLIBS_DEBUG}>

     $<$<CONFIG:Release>:${MYLIBS_OPTIMIZED}>



But since I use a third party find module the MYLIB_LIBRARIES variable is not separated into these categories. I was hoping to avoid rewriting this external find module.



You can perfectly write a CMake helper function which takes MYLIB_LIBRARIES as input and spit out MYLIBS_DEBUG, MYLIBS_OPTIMIZED as an output.

This way you don't have to rewrite 3rd party code and keep your code clean.



--

Eric
--

Powered by www.kitware.com<http://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:
https://cmake.org/mailman/listinfo/cmake
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20181004/3faafaf9/attachment-0001.html>


More information about the CMake mailing list