conan: [problem] cmake_multi INTERFACE_LINK_LIBRARIES uses generator expressions, does not support custom build configurations

I hope I have understood this problem correctly, and that I’ll be able to explain it properly.

The cmake_multi generator defines imported targets and sets properties on them that specify where the include and library files are located.

Here’s an example for GLEW, formatted for a bit of clarity:

CONAN_PKG::glew INTERFACE_LINK_LIBRARIES = 

CONAN_PKG::opengl;
CONAN_PKG::glu;

$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>;

$<$<CONFIG:Release>:
  CONAN_LIB::glew_glew32release;
  CONAN_PKG::opengl;
  CONAN_PKG::glu;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>
>;
$<$<CONFIG:RelWithDebInfo>:
  ;
  CONAN_PKG::opengl;
  CONAN_PKG::glu;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>
>;
$<$<CONFIG:MinSizeRel>:
  ;
  CONAN_PKG::opengl;
  CONAN_PKG::glu;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>
>;
$<$<CONFIG:Debug>:
  CONAN_LIB::glew_glew32ddebug;
  CONAN_PKG::opengl;
  CONAN_PKG::glu;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;
  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>
>

cmake_multi seems to forgo the use of per-configuration properties such as INTERFACE_LINK_LIBRARIES_DEBUG or INTERFACE_LINK_LIBRARIES_RELEASE, preferring to set the config-independent properties and using generator expressions to ensure the correct files are used for each configuration.

The problem is that this only seems to work for the predefined configurations Release, RelWithDebInfo, MinSizeRel, and Debug. When the CMake script or user adds extra configurations, e.g. DebugSpecial, then tries to map that configuration to Debug for imported dependencies via set(CMAKE_MAP_IMPORTED_CONFIG_DEBUGSPECIAL Debug), the library won’t be found: CMake will probably first try looking for the property INTERFACE_LINK_LIBRARIES_DEBUGSPECIAL, find that it doesn’t exist, and based on the defined mapping try to fall back to INTERFACE_LINK_LIBRARIES_DEBUG, which won’t exist either. Lastly, it would fall back to INTERFACE_LINK_LIBRARIES, which unfortunately only contains generator expressions for the predefined configurations.

Is this a known problem ?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (10 by maintainers)

Most upvoted comments

@memsharded I’m still trying to work my way through CMakeDeps - is it correct that CMakeDeps no longer uses the CONAN_PKG:: namespace on dependency targets ?

Yes, CMakeDeps use native find_package(). No need to change CMakeLists.txt at all to account for Conan specific targets.

Even if I don’t like it very much, there is the relatively popular cmake-conan integration (https://github.com/conan-io/cmake-conan) that helps calling conan install directly from CMake, as a consumer. It supports the GENERATORS argument to specify which generator you want to use (even your own one, if you wanted), it is not restricted by the cmake-conan tool, it will just pass the value to Conan.

Otherwise, my preference is having a conanfile.txt defined, for consumption and let the flow be:

$ git clone .... repo && cd repo
$ conan install .
$ cmake ... -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake

This is more or less the intended user experience. Having the conan install explicit helps understanding many more things, and give power and flexibility with low cost (using yet another abstraction as cmake-conan also has a cost)

The new integrations as CMakeDeps use native find_package() so in theory it is not necessary to modify the CMakeLists.txt at all either.