无sudo本地编译工具时ld无法找到-lstdc++的问题
我最近尝试在不使用sudo权限的情况下,通过CMake本地编译一款工具,但链接器ld抛出了错误:
/usr/bin/ld: cannot find -lstdc++
我的ld搜索路径如下:
$ ld --verbose | grep SEARCH_DIR | tr -s ' ;' \012 SEARCH_DIR("/usr/x86_64-redhat-linux/lib64") SEARCH_DIR("/usr/lib64") SEARCH_DIR("/usr/local/lib64") SEARCH_DIR("/lib64") SEARCH_DIR("/usr/x86_64-redhat-linux/lib") SEARCH_DIR("/usr/local/lib") SEARCH_DIR("/lib") SEARCH_DIR("/usr/lib")
而且/usr/lib64/目录下确实存在libstdc++.so.6,我也已经把/usr/lib64/加入了LD_LIBRARY_PATH环境变量,但问题依然存在。针对这个情况,我有两个问题:
问题1:是否是精确名称匹配导致ld无法找到该库?
完全正确!就是精确名称匹配的问题。
当你用-lstdc++参数时,ld的规则是去寻找名为libstdc++.so的文件(注意是不带版本号的.so后缀)。而你现有的libstdc++.so.6是版本化的库文件,虽然它是一个软链接指向具体的库本体,但链接器在编译链接阶段,只认不带版本号的.so文件——这是GNU链接器的约定:-lxxx对应libxxx.so。
你可以去/usr/lib64/目录下确认,大概率没有libstdc++.so这个文件或软链接,这就是问题的核心。
问题2:如何在不使用sudo权限的前提下让ld识别该库?
这里有几个无需sudo权限的可行方案,按推荐程度排序:
方法1:本地创建软链接,指定CMake搜索路径
在自己的用户目录下创建一个临时库目录,把libstdc++.so.6软链接成libstdc++.so,再告诉CMake去这个目录找库:
- 创建本地库目录:
mkdir -p ~/local_lib - 建立软链接:
ln -s /usr/lib64/libstdc++.so.6 ~/local_lib/libstdc++.so - 编译时指定CMake的库搜索路径:
cmake -DCMAKE_LIBRARY_PATH=~/local_lib .. make
方法2:直接在CMakeLists.txt中指定库的绝对路径
如果你有权限修改项目的CMakeLists.txt,可以直接添加对版本化库的引用,跳过名称匹配:
target_link_libraries(你的目标程序名称 PRIVATE /usr/lib64/libstdc++.so.6)
这样ld会直接使用这个绝对路径的库文件,无需再找libstdc++.so。
方法3:临时修改LDFLAGS环境变量
在编译前临时设置LDFLAGS,利用GNU ld的特殊语法直接指定带版本号的库:
export LDFLAGS="-L/usr/lib64 -l:libstdc++.so.6" cmake .. make
这里的-l:libstdc++.so.6是GNU ld的专属写法,允许你直接指定完整的库文件名,跳过自动添加lib前缀和.so后缀的默认逻辑。
内容的提问来源于stack exchange,提问作者galactica

