Using Generator Expressions with the STATIC_LIBRARY_OPTIONS property

I’m having trouble adding a generator expression that wraps a list to the
STATIC_LIBRARY_OPTIONS property for Windows Visual Studios 2017. I’m using
cmake version 3.23.1

I’m not sure if I’m encountering some sort of quoting issue, or if this is a
defect with the tool.

The following simple CMake file illustrates the problem

cmake_minimum_required (VERSION 3.15)

include(CMakePrintHelpers)


set(TARGET    StaticLibTest)

project(${TARGET})

# Create dummy file: lib.cpp
file(WRITE  lib.cpp "#include <stdio.h>\n")
file(APPEND lib.cpp "void mainlib(void)\n")
file(APPEND lib.cpp "{\n")
file(APPEND lib.cpp "    printf(\"Hello world\\n\");\n")
file(APPEND lib.cpp "}\n")


add_library(${TARGET} STATIC)

target_sources(${TARGET} PRIVATE lib.cpp)

# Adding one value works
#
# This results in:
#    %(AdditionalOptions) /machine:x64 ABC
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS ABC)



# Think of ALIST as a list of paths to add
#
# Adding a list of simple values works
#
# This results in:
#     %(AdditionalOptions) /machine:x64 ABC PDQ XYZ LDR
set(ALIST PDQ XYZ LDR)
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS ${ALIST})



# Adding a simple generator expression works
#
# This results in:
#    %(AdditionalOptions) /machine:x64 ABC PDQ XYZ LDR releaseLib
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS "$<$<CONFIG:Release>:releaseLib>")




# add a generator expression with a list of values does not work
#
# This results in:
#    %(AdditionalOptions) /machine:x64 ABC PDQ XYZ LDR releaseLib ""$"<1:releaseLib01" releaseLib02 "releaseLib03>"
#
set(RLIST releaseLib01 releaseLib02 releaseLib03)
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS "$<$<CONFIG:Release>:${RLIST}>")

We can see the results of this in Visual Studio by:

  1. Open the properties for StaticLibTest
  2. Set Configuration to Release
  3. Navigate to Librarian → Command Line
  4. Observe the “Additional Options” dialog at the bottom of the window.

The solution file for this has

%(AdditionalOptions) /machine:x64 ABC PDQ XYZ LDR releaseLib ""$"<1:releaseLib01" releaseLib02 "releaseLib03>"

and causes the link to fail.

while I expect to see:

%(AdditionalOptions) /machine:x64 ABC PDQ XYZ LDR releaseLib releaseLib01 releaseLib02 releaseLib03

Is this a quoting problem? If so how can I do this correctly?

It is clearly an error on how this property is handled: the list is expanded before genex evaluation, so preventing a correct evaluation when a list is specified as part of the genex.

Can you create an issue for this problem? Add this description as part of the issue.

In the meantime, you can work around the problem by using $<SEMICOLON> genex:

set(RLIST PDQ XYZ LDR)
list(JOIN RLIST "$<SEMICOLON>" FIXED_RLIST)
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS "$<$<CONFIG:Release>:${FIXED_RLIST}>")

Thank you @marc.chevrier. Issue #24258 has been opened.

The proposed workaround worked too!

This workaround even worked for the more complex case that I originally encountered until I trimmed it down to these more simple cases listed above.

The issue I originally encountered was closer to the following:

set(RLIST
    "$<$<CONFIG:Debug>:debugLib01;debugLib02>"
    "$<$<CONFIG:Release>:releaseLib01;releaseLib02>"
    "$<$<CONFIG:RelWithDebInfo>:rwdLib01;rwdLib02>")
list(JOIN RLIST "$<SEMICOLON>" RLIST)
set_property(
    TARGET ${TARGET} APPEND PROPERTY
    STATIC_LIBRARY_OPTIONS "${RLIST}")

In my case RLIST came from reading another targets INTERFACE_LINK_LIBRARIES property, which was a jumble of Debug/Release/etc. logic