3
votes

pkg_check_modules from FindPkgConfig gives MYLIBRARY_LDFLAGS and MYLIBRARY_CFLAGS that are ordinary CMake lists (with semicolon-separator).

The set_target_properties and set_property accept just one string.

So that doesn't work because it doesn't expand the list:

set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY LINK_FLAGS ${MYLIBRARY_LDFLAGS})

This gives same thing with the semicolons inside:

set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY LINK_FLAGS "${MYLIBRARY_LDFLAGS}")

set_target_properties expands into multiple strings when unquoted and into one string with semicolons when quoted.

How am I supposed to use that?

2

2 Answers

4
votes

Common workflow with libraries searched by pkg-config within CMake:

# Use pkg-config for search library `xxx`.
pkg_check_modules(XXX xxx)

# Build target which uses given library

# The only command which has no target-oriented equivalent.
# But see comments after the code.
link_directories(${XXX_LIBRARY_DIRS}) 

# Two global commands belows can be replaced by target-oriented equivalent
# after creation of the target.
include_directories(${XXX_INCLUDE_DIRS})
add_compile_options(${XXX_CFLAGS_OTHER})

# Create target
add_executable(my_exe ...) # Or add_library()

# The only target-oriented command, which has no global equivalent.
target_link_libraries(my_exe ${XXX_LDFLAGS_OTHER}) # It is OK to have link flags here
target_link_libraries(my_exe ${XXX_LIBRARIES}) # Can be combined with previous call.

Note, that we use XXX_LDFLAGS_OTHER variable instead of XXX_LDFLAGS one. This is because XXX_LDFLAGS includes -l and -L options for which CMake has more suitable commands. Similar reason about usage of XXX_CFLAGS_OTHER.


Currently, CMake doesn't recommend to use link_directories command but use absolute paths to libraries in target_link_libraries call. One can extract absolute paths to libraries, listed by pkg-config, with use of find_library command:

...
# Instead of using `link_directories`, collect absolute paths to libraries.
set(XXX_LIBS_ABSOLUTE)
foreach(lib ${XXX_LIBRARIES})
    # Choose name of variable, which will contain result of `find_library`
    # for specific library.
    set(var_name XXX_${lib}_ABS)
    # Search library under dirs, returned by pkg-config.
    find_library(${var_name} ${lib} ${XXX_LIBRARY_DIR})
    list(APPEND XXX_LIBS_ABSOLUTE ${${var_name}})
endforeach()

# Instead of `target_link_libraries(my_exe ${XXX_LIBRARIES})`
target_link_libraries(my_exe ${XXX_LIBS_ABSOLUTE})
0
votes

I'm not sure if this is how it is intended to be used, but this should work:

string(REPLACE ";" " " MYLIBRARY_LDFLAGS "${MYLIBRARY_LDFLAGS}")
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " ${MYLIBRARY_LDFLAGS}")

The string(REPLACE) command will change the list in a string separated by spaces, and that you can therefore use for the LINK_FLAGS property

The prepended white space in " ${MYLIBRARY_LDFLAGS}" and the APPEND_STRING instead of APPEND will ensure that the resulting string is usable as LINK_FLAGS even if the property is not empty.