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

时间:2015-02-24 03:58:55

标签: cmake

某些CMake内置模块(例如FindPythonLibs)设置了一些包含库列表的变量,因此您有一组用于调试和发布版本的库。当您打印其中一个时,它看起来像optimized;C:\foo\python27.lib;debug;C:\foo\python27_d.lib

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

  1. 如果我只是将此字符串传递给target_link_libraries(),它是否总是根据我的CMAKE_BUILD_TYPE选择正确的字符串?
  2. 即使只是弄明白,我仍然需要提取它要选择的路径,因为我需要这条路径用于其他目的。因此,例如,如果CMAKE_BUILD_TYPE=Debug,我需要字符串C:\foo\python27_d.lib,以便我可以在我的脚本中使用它做其他事情。
  3. 通常如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

如果查看target_link_libraries foo(A;B;C),您会看到您传递了额外的参数来指示库的优化或调试版本。

需要注意的是,CMake的语法使得foo(A B C)等同于target_link_libraries

所以你根本不需要解析字符串; CMake有趣的语法为您处理:CMake扩展变量值,然后将其扩展为target_link_libraries(mytarget ${PythonLibs_LIBRARIES}) 的单独参数:

target_link_libraries(mytarget optimized;C:\foo\python27.lib;debug;C:\foo\python27_d.lib)

扩展为

target_link_libraries(mytarget optimized C:\foo\python27.lib debug C:\foo\python27_d.lib)

扩展为

add_custom_command(TARGET mytarget POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy C:\foo\python27_d.dll $<TARGET_FILE_DIR:mytarget>)
  1. 是的。

  2. 我不确定是否有任何直接的方式来询问链接到哪个版本的特定库。也许你正在尝试做什么的一些细节会提出一个解决方案。无论如何,也许使用syntax可以做你需要的事情,或者generator expressions可以提供帮助。


  3. 我想要复制一个你可以使用的文件:

    {{1}}

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

答案 1 :(得分:1)

这不是一个完美的方法,但你可以尝试一下。查找Boost的包返回所请求组件的混合列表。为了同样的目的,我完全按照你的意愿行事。也许你可以根据自己的需要进行调整。

# 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)