最近一个项目里的 CMakeList.txt 是在网上找来的例子改的, 里面有这么一句:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/opt/boost/lib -lboost_system -lboost_program_options")
平时在 mac 上开发构建, 一直没什么问题, 今天拿到 linux 机器上却怎么也构建不成功, 一直报 Undefined boost::system::system_category
, 这个符号显然是定义在 libboost_system 里的, 而这库上面也链上了, 为何还是不行呢?
无奈之下, make 的时候加上了 VERBOSE=1
, 这才发现问题 --- cmake 生成的链接指令竟然是:
/usr/bin/c++ -std=c++11 -I/usr/local/opt/boost/include -L/usr/local/opt/boost/lib -L/usr/local/lib -lpthread -lboost_system CMakeFiles/demo.dir/demo.cpp.o -o demo
也就是说把 linker flag 放到目标文件前面了, 我们知道 ld 的链接规则是 "未定义的符号往后找", 所以这样肯定是补丁的.
但是我的 mac 机器上也是这个 CMakeList.txt 文件, 却并没有这个问题, 好奇之下我又看了下 mac 机器上生成的链接指令, 发现是这样的:
/Library/Developer/CommandLineTools/usr/bin/c++ -std=c++11 -I/usr/local/opt/boost/include -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/usr/local/opt/boost/lib CMakeFiles/demo.dir/demo.cpp.o -o demo -lboost_system
看来, mac 机器上生成的链接指令是正确的. 而且, 我在 mac 上用的 cmake 和 linux 的版本是一样的, 都是 3.11. 这就呵呵了...
我一直觉得 linux 是最适合做开发的系统, 没想到 cmake 这么重要的工具, linux 竟不如 mac 维护的好.
不过按常理来讲这么明显的问题竟然能被我碰到, 一定是我使用的方式不对了. 果然, 查了一下发现, CMAKE_EXE_LINKER_FLAGS 这个变量好像就没几个人用, 网上普遍建议的是使用 target_link_libraries 的写法 (见参考1). (要加链接搜索目录的就使用 link_directories()
)
后来我在 cmake 官网上也看到了他们的例子用的是 target_link_libraries (见参考2). 看来以后还是少从网上扒不靠谱代码.
参考
1. http://cmake.3232098.n2.nabble.com/How-to-use-CMAKE-EXE-LINKER-FLAGS-correctly-td7593495.html
2. cmake 官方 tutorial: https://cmake.org/cmake-tutorial/
Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!
Reply !stop to disable the comment. Thanks!