【问题标题】:Path to target output file目标输出文件的路径
【发布时间】:2011-05-19 18:40:41
【问题描述】:

我有一个由add_library 创建的.so 库目标,并且需要将此库的绝对路径传递给外部脚本。现在我有${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}LangShared${CMAKE_SHARED_LIBRARY_SUFFIX}LIBRARY_OUTPUT_PATH 在我的CMakeLists.txt 中定义)。这对我来说看起来像是硬编码,因为一旦重命名目标或更改其某些属性,它就会中断。有没有办法获得add_library 输出的绝对路径?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    您应该为此使用generator expression

    来自add_custom_command 的文档和生成器表达式的文档:

    COMMAND 的参数可以使用“生成器表达式”...

    生成器表达式在生成系统生成期间进行评估,以生成特定于每个生成配置的信息。

    在这种情况下,假设您的库目标名为“MyLib”,表示构建库的完整路径的生成器表达式将是:

    $<TARGET_FILE:MyLib>
    

    【讨论】:

    • 这很令人沮丧,因为add_custom_[...] 命令都不允许您调用宏——它们只能运行外部程序。
    • 是的,要调用宏,您需要将其添加到独立的 CMake 脚本文件中,并使用 -P 参数从命令中调用 CMake。缺点(除了过于复杂之外)是脚本文件中的宏无法访问主 CMake 进程中的任何当前变量 - 您在调用 CMake 时也需要传递它们。例如add_custom_command(... COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -P"path/to/script_with_macro.cmake")
    • 或者,如果在 cmake 宏中使用,$&lt;TARGET_FILE:${target_macro_parameter}&gt;
    • 生成器表达式仅用作与“生成”步骤相关的少数函数的参数。如果您在“配置”步骤中想要这样做,则生成器表达式不起作用。看到这个问题:stackoverflow.com/questions/56470020/…
    【解决方案2】:

    试试:

    get_property(fancy_lib_location TARGET fancy_lib PROPERTY LOCATION)
    message (STATUS "fancy_lib_location == ${fancy_lib_location}")
    

    其中fancy_lib 是使用add_library (fancy_lib SHARED ...) 创建的目标。

    我发现它可以直接与 Makefile 生成器一起使用,但对于 Visual Studio 生成器还有更多工作要做,因为 fancy_lib_location 的值不是您所期望的:

    1. fancy_lib_location 将包含对 Visual-Studio 特定 $(OutDir) 引用的嵌入式引用,您必须将其替换为 CMAKE_BUILD_TYPE CMake 变量的值(解析为 DebugRelease 之类的值) .
    2. 至少对于 CMake 2.8.1,至少在 Visual Studio 目标上,并且如果您设置了 CMAKE_DEBUG_POSTFIX 变量,那么它将包含在值中(可能或可能不是错误,我不知道)。

    【讨论】:

    • 对于第 1 点,您可以获得LOCATION 的每个配置版本,即LOCATION_DEBUGLOCATION_RELEASE 等。这完全解决了路径。对于第 2 点,这似乎已修复为 v2.8.10
    • @Ose 不幸的是,${CMAKE_BUILD_TYPE} 仅在基于 make 的生成器中受支持,因此在使用 Visual Studio 等 IDE 时,您的解决方案可能会中断。
    • Policy CMP0026 in Cmake 3.0 及更高版本)不允许以这种方式使用 LOCATION 属性。首选生成器表达方式。
    • 使用 cmake v3.15.5,这会产生以下错误:可能无法从目标读取 LOCATION 属性。直接将目标名称与 add_custom_command 一起使用,或根据需要使用生成器表达式 $
    • @harish 我已经多年没有使用 cmake 了,所以我的答案现在可能已经严重过时,因此现在“过时”了。
    【解决方案3】:

    为了扩展@bgooddr 的答案,这里有一个获取目标位置的 CMake 函数:

    function(get_fancy_lib_location)
        set(options)
        set(multiValueArgs LIB)
        set(oneValueArgs LOCATION)
        cmake_parse_arguments(get_fancy_lib_location "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
        message (STATUS "fancy_lib  == ${get_fancy_lib_location_LIB}")
    
        get_property(fancy_lib_location TARGET "${get_fancy_lib_location_LIB}" PROPERTY LOCATION)
        message (STATUS "fancy_lib_location == ${fancy_lib_location}")
    
        set(${get_fancy_lib_location_LOCATION} ${fancy_lib_location})
    endfunction()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2021-11-25
      • 2014-04-18
      • 2014-09-26
      相关资源
      最近更新 更多