CMake生成静态库的-L<path>和-l<lib>链接标志

9

我正在使用CMake 2.8来构建一个基于MQX OS的应用程序(使用CodeWarrior)。
CMake项目主要构建一组静态库(比如说LIB1和LIB2)。
然后我在最终可执行文件的cmake规则中引用这些库。

target_add_executable(X ${some_sources})
target_link_libraries(X LIB1 LIB2)

我的问题是一些符号在多个库中定义。
因此,链接命令可能如下所示:
mwldarm <args> -o <output> <objects> /path/to1/libLIB1.a /path/to2/libLIB2.a

会导致多个符号定义错误。 相反,我希望CMake生成这样的链接命令:
mwldarm <args> -o <output> <objects> -L/path/to1 -L/path/to2 -lLIB -lLIB2
问题:如何从CMAKE获取以下变量?
  • 库目录标志(例如:-L/path/to1 -L/path/to2
  • 库链接标志(例如:-lLIB -lLIB2

我已经阅读了关于RPATH的内容,但似乎只涉及共享库。我是对的吗?

谢谢您的帮助。
非常感激。


1
尽管存在链接线问题,但拥有多个符号似乎并不是一件好事。您是否考虑将LIB1和LIB2的公共部分重构为一个唯一的库,作为两者的依赖项? - Massimiliano
这绝对是我所认为的!我授予你的答案,因为在我看来它是正确的(我意味着)。 - maqui
3个回答

3

看起来,CMP0003 策略可能是你需要的。

要使用它,请在你的 CMakeLists.txt 开始处添加以下行:

CMAKE_POLICY( SET CMP0003 OLD )

另一种可能性是直接设置依赖项和搜索路径,但这不是最干净的方法。假设您的库名为 liba.alibb.a,则:
LINK_DIRECTORIES( ${paths_to_search_for} )
TARGET_ADD_EXECUTABLE(X ${some_sources} )
ADD_DEPENDENCIES(X LIB1 LIB2)
TARGET_LINK_LIBRARIES(X a b )

请注意,在这种情况下,ab不是cmake的目标,因此需要一些机制来正确设置依赖关系。

我在CMAKE文档中进行了搜索,并发现与您相同的内容。在发布此消息之前,我进行了测试。然而,无论是我使用不正确,还是它什么也没做,因为由cmake生成的链接命令行完全相同,无论是否使用CMP0003策略(OLD或NEW!)。 - maqui
1
我确认在我的情况下这不能完成工作,因为所有库都是由同一个cmake项目构建的。正如CMAKE文档中CMP0003策略描述所说:当链接行上的所有项都具有已知路径时,CMake不会检查此策略,因此它没有任何影响。 - maqui
政策并非功能切换。http://www.cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cd4fa896b。请不要这样做,也请不要建议其他人这样做。 - steveire

1

-1

我认为CMP0003用于根据官方文档中的描述,开启/关闭自动添加搜索路径的功能。

通过完整路径链接的库不再产生链接器搜索路径。

而不是替换路径名为-l

在链接库时,如果该库是CMake已知的目标,则CMake始终将相关的-L-l选项替换为库的路径名。这对于链接静态库可能不是问题。但对于可执行文件来链接共享库,则可能会出现问题。然后我找到了一个黑客方法,像下面的代码一样,使用-L-l而不是绝对路径来解决链接共享库的问题。

# Find out the link.txt      
set(LINK_TXT "${CMAKE_BINARY_DIR}/${ToLinkLib}/CMakeFiles/${ToLinkLIb}.dir/link.txt")

# Add the searching path into link command
add_custom_command(TARGET ${YourTarget} PRE_BUILD
  COMMAND sed ARGS -ie "\"s;[[:blank:]]-l; -L${LIBRARY_OUTPUT_PATH} -l;\"" ${LINK_TXT}
  DEPENDS ${LINK_TXT}
  COMMENT "Hacking CMake: edit __link.txt__ to use -l instead of path to link internal library ...")

# NOTE: Dont't missing the `-l'. 
target_link_libraries(${YourTarget} -l${ToLinkLib})

当然,这只是一种hack方法,可能无法与所有版本的CMake完全兼容。


更新:为什么链接共享库可能会出现问题?

当我运行一个交叉编译为Android的可执行文件时,它链接了由相同的CMake脚本构建的共享库,我遇到了链接失败的问题。在使用上述黑客方法获取新版本后,我可以使用以下命令运行我的可执行文件。

 $ LD_LIBRARY_PATH=. ./the_exe opts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接