Skip to content

Incorrect escaping of dollar sign '$' in generator expressions in INTERFACE_LINK_LIBRARIES in file generated by install(EXPORT)

CMake escapes the '$' character in generator expressions of install(EXPORT) generated files, when it shouldn't.

Sample project:

cmake_minimum_required(VERSION 3.16)
project(escape_exported_genexes VERSION 2.0.0 LANGUAGES CXX)
add_library(mylib SHARED main.cpp)
target_link_libraries(mylib PUBLIC "optimized" "/custom_release.a" "debug" "/custom_debug.a")

install(
   TARGETS mylib
     EXPORT mylib-targets
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(
   EXPORT mylib-targets
     DESTINATION "lib"
     FILE mylib-config.cmake)

Configure with cmake . and the contents of the file at CMakeFiles/Export/lib/mylib-config.cmake will have this piece of code

# Create imported target mylib
add_library(mylib SHARED IMPORTED)

set_target_properties(mylib PROPERTIES
  INTERFACE_LINK_LIBRARIES "\$<\$<NOT:\$<CONFIG:DEBUG>>:/custom_release.a>;\$<\$<CONFIG:DEBUG>:/custom_debug.a>"
)

Note how each $ is escaped with a backslash.

This happens due to the cmExportFileGeneratorEscape(property.second) call in cmExportFileGenerator::GenerateInterfaceProperties in cmake/Source/cmExportFileGenerator.cxx:583 which calls cmOutputConverter::EscapeForCMake.

The $ escaping is meant to avoid variable expansion, but I don't think it's needed for generator expressions.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information