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

如何在CMake中解析优化/调试库字符串?,cmake,Cmake,某些CMake内置模块(如FindPythonLibs)设置了一些变量,这些变量将包含库的列表,这样您就有了一组用于调试和发布构建的库。当您打印其中一个时,它看起来像是optimized;C:\foo\python27.lib;调试;C:\foo\python27\u d.lib 现在,至少在Windows上,您可以链接的python只有一个版本——与您的构建配置相匹配的版本。如果您正在构建调试,则必须针对调试python进行链接,类似地,对于发布版也是如此。因此,当只有一个值是相关的时,处理这

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

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

  • 如果我只是按原样将此字符串传递给target_link_libraries(),它是否总是根据我的
    CMAKE_BUILD_TYPE
    选择正确的字符串
  • 即使它只是想出来,我仍然需要提取它将要选择的路径,因为我需要这个路径用于另一个目的。因此,例如,如果
    CMAKE\u BUILD\u TYPE=Debug
    ,我需要字符串
    C:\foo\python27\u d.lib
    ,这样我就可以在脚本中用它做其他事情
  • 通常如何解决此问题?

    如果查看for
    目标链接库
    ,您将看到向其传递额外参数以指示库的优化或调试版本

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

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

    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)
    
    扩展到

    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>)
    
    add_custom_命令(TARGET mytarget POST_BUILD
    COMMAND${CMAKE_COMMAND}-E copy C:\foo\python27\u d.dll$)
    

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

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

    #好和坏是单个字符串,输入是一个用字符串包装的列表
    #输出是列表的名称
    宏(过滤器列表输入输出良好不良)
    set(LST${INPUT})#我们能避免这种情况吗?
    设置(选择我是)
    foreach(列表LST中的元素)
    if(${ELEMENT}STREQUAL-general或${ELEMENT}STREQUAL${GOOD})
    设置(选择我是)
    elseif(${ELEMENT}STREQUAL${BAD})
    设置(PICKME编号)
    埃尔塞夫(皮克梅)
    字符串(REPLACE.lib.dll${ELEMENT})
    列表(追加${OUTPUT}${DLL})
    endif()
    endforeach()
    endmacro(过滤器列表)
    
    然后你可以使用这样的宏,比如

    FILTER\u LIST(“${Boost\u LIBRARIES}”Boost\u Debug\u dll调试优化)
    安装(文件${BOOST\u Debug\u DLLS}目标“bin”配置调试组件BOOST)
    过滤器列表(“${Boost\u LIBRARIES}”Boost\u发行版\u DLL优化调试)
    安装(文件${BOOST\u Release\u DLLS}目标“bin”配置发布组件BOOST)
    
    根据选择链接的版本,我想计算相应DLL的路径并将其复制到特定文件夹。因此,如果它选择C:\foo\python27\u d.lib,我将使用正则表达式替换来计算字符串C:\foo\python27\u d.dll,然后将该文件复制到其他位置。但假设我可以确定选择了哪个版本。我知道这是调试。那么,从这个字符串中获取调试库路径的最优雅的方法是什么。