如何在CMake中解析优化/调试库字符串



某些CMake内置模块(如FindPythonLibs)会设置一些包含库列表的变量,这样您就有了一组用于调试和发布构建的库。当你打印其中一个时,它看起来像optimized;C:foopython27.lib;debug;C:foopython27_d.lib

现在,至少在Windows上,只有一个版本的python可以链接,那就是与您的构建配置匹配的版本。如果您正在构建Debug,则必须链接到Debug-python,发布时也是如此。因此,当只有一个值是相关的时,处理这些多个值对我来说没有什么意义。所以我有两个问题:

  1. 如果我只是按原样将此字符串传递给target_link_libraries(),它是否总是根据我的CMAKE_BUILD_TYPE选择正确的字符串
  2. 即使它真的弄清楚了,我仍然需要提取它将要选择的路径,因为我需要这条路径用于另一个目的。因此,例如,如果是CMAKE_BUILD_TYPE=Debug,我需要字符串C:foopython27_d.lib,这样我就可以在脚本中使用它做其他事情

人们通常如何解决这个问题?

如果查看target_link_libraries的语法,您会发现您向它传递了额外的参数,以指示库的优化或调试版本。

需要注意的是,CMake的语法使foo(A;B;C)等效于foo(A B C)

因此,您根本不需要解析字符串;CMake有趣的语法为您处理它:CMake扩展变量值,然后将其扩展为target_link_libraries:的单独参数

target_link_libraries(mytarget ${PythonLibs_LIBRARIES})

扩展到

target_link_libraries(mytarget optimized;C:foopython27.lib;debug;C:foopython27_d.lib)

扩展到

target_link_libraries(mytarget optimized C:foopython27.lib debug C:foopython27_d.lib)
  1. 是的。

  2. 我不确定是否有任何直接的方法来询问某个特定库的链接版本。也许一些关于你到底想做什么的细节会建议一个解决方案。无论如何,也许生成器表达式的一些使用可以满足您的需要,或者这个答案可能会有所帮助。


我认为要复制一个文件,你可以使用这样的东西:

add_custom_command(TARGET mytarget POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy C:foopython27_d.dll $<TARGET_FILE_DIR:mytarget>)

我仍然不确定如何获得目标所依赖的库的路径。

这不是一个完美的方法,但您可以尝试一下。Boost的Find包返回一个请求组件的混合列表。我做你想做的事也是出于同样的目的。也许你可以根据自己的需要进行调整。

# GOOD & BAD are single strings, INPUT is a list wrapped in string
# OUTPUT is a name for a list
macro(FILTER_LIST INPUT OUTPUT GOOD BAD)
  set(LST ${INPUT})   # can we avoid this?
  set(PICKME YES)
  foreach(ELEMENT IN LISTS LST)
    if(${ELEMENT} STREQUAL general OR ${ELEMENT} STREQUAL ${GOOD})
      set(PICKME YES)
    elseif(${ELEMENT} STREQUAL ${BAD})
      set(PICKME NO)
    elseif(PICKME)
      string(REPLACE .lib .dll DLL ${ELEMENT})
      list(APPEND ${OUTPUT} ${DLL})
    endif()
  endforeach()
endmacro(FILTER_LIST)

然后你可以使用像这样的宏

FILTER_LIST("${Boost_LIBRARIES}" BOOST_Debug_DLLS debug optimized)
install(FILES ${BOOST_Debug_DLLS} DESTINATION "bin" CONFIGURATIONS Debug COMPONENT Boost)
FILTER_LIST("${Boost_LIBRARIES}" BOOST_Release_DLLS optimized debug)
install(FILES ${BOOST_Release_DLLS} DESTINATION "bin" CONFIGURATIONS Release COMPONENT Boost)

最新更新