Gcc 仅静态链接某些库
在使用GCC链接时,如何仅将特定库静态链接到二进制文件Gcc 仅静态链接某些库,gcc,linker,static-libraries,Gcc,Linker,Static Libraries,在使用GCC链接时,如何仅将特定库静态链接到二进制文件 gcc-静态…尝试静态链接所有链接的库,但我没有得到其中一些库的静态版本(例如:libX11)。来自ld的手册页(这不适用于gcc),参考--static选项: 您可以多次使用此选项 命令行上的时间:它影响 库搜索-l选项,其中 跟着它走 一种解决方案是将动态依赖项放在命令行上的--static选项之前 另一种可能是不使用--static,而是提供静态对象文件的完整文件名/路径(即不使用-l选项),以便静态链接到特定库中。例如: # ech
gcc-静态…
尝试静态链接所有链接的库,但我没有得到其中一些库的静态版本(例如:libX11)。来自ld
的手册页(这不适用于gcc),参考--static
选项:
您可以多次使用此选项
命令行上的时间:它影响
库搜索-l选项,其中
跟着它走
一种解决方案是将动态依赖项放在命令行上的--static
选项之前
另一种可能是不使用--static
,而是提供静态对象文件的完整文件名/路径(即不使用-l选项),以便静态链接到特定库中。例如:
# echo "int main() {}" > test.cpp
# c++ test.cpp /usr/lib/libX11.a
# ldd a.out
linux-vdso.so.1 => (0x00007fff385cc000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f9a5b233000)
libm.so.6 => /lib/libm.so.6 (0x00007f9a5afb0000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f9a5ad99000)
libc.so.6 => /lib/libc.so.6 (0x00007f9a5aa46000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a5b53f000)
正如您在示例中看到的,libX11
不在动态链接库的列表中,因为它是静态链接的
注意:。因此
文件始终是动态链接的,即使指定了完整的文件名/路径。一些加载程序(链接器)提供了打开和关闭动态加载的开关。如果GCC正在这样一个系统(Solaris,可能还有其他系统)上运行,那么您可以使用相关的选项
如果您知道要静态链接哪些库,只需在链接行中按完整路径指定静态库文件。
gcc-lsome\u dynamic\u lib code.c some\u static\u lib.a
您也可以使用ld
选项-Bdynamic
gcc <objectfiles> -static -lstatic1 -lstatic2 -Wl,-Bdynamic -ldynamic1 -ldynamic2
gcc-static-lstatic1-lstatic2-Wl,-Bdynamic-ldynamic1-ldynamic2
之后的所有库(包括由gcc自动链接的系统库)都将动态链接。据我所知,问题如下。您有几个库,一些是静态库,一些是动态库,还有一些是静态库和动态库gcc的默认行为是链接“大部分是动态的”。也就是说,gcc在可能的情况下链接到动态库,但在其他情况下返回到静态库。当您将-static选项用于gcc时,行为是仅链接静态库,如果找不到静态库,即使存在适当的动态库,也会以错误退出 另一个选项,我曾多次希望gcc拥有,我称之为——大部分是静态的,本质上与——动态的(默认设置)相反-如果存在的话,大部分是静态的会倾向于链接静态库,但会退回到动态库 此选项不存在,但可以使用以下算法进行模拟:
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 [--exclude <lib_name>]. . . <link_command>"
fi
exclude=()
lib_path=()
while [ $# -ne 0 ]; do
case "$1" in
-L*)
if [ "$1" == -L ]; then
shift
LPATH="-L$1"
else
LPATH="$1"
fi
lib_path+=("$LPATH")
echo -n "\"$LPATH\" "
;;
-l*)
NAME="$(echo $1 | sed 's/-l\(.*\)/\1/')"
if echo "${exclude[@]}" | grep " $NAME " >/dev/null; then
echo -n "$1 "
else
LIB="$(gcc $lib_path -print-file-name=lib"$NAME".a)"
if [ "$LIB" == lib"$NAME".a ]; then
echo -n "$1 "
else
echo -n "\"$LIB\" "
fi
fi
;;
--exclude)
shift
exclude+=(" $1 ")
;;
*) echo -n "$1 "
esac
shift
done
echo
在我的系统返回上:
gcc -o test test.c "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libdl.a" "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libpthread.a"
或排除:
mostlyStatic --exclude dl gcc -o test test.c -ldl -lpthread
然后我得到:
gcc -o test test.c -ldl "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libpthread.a"
您还可以为gcc库使用:-static libgcc-static libstdc++
标志
请记住,如果
libs1.so
和libs1.a
都存在,则链接器将选择libs1.so
,如果它在-Wl,-Bstatic
之前或-Wl,-Bdynamic
之后。在调用-ls1
之前,不要忘记传递-L/libs1 library location/
,还有-L:libstatic1.gcc中-L选项的一个
(减去L冒号)变体,可用于链接静态库(感谢)。有文件记录吗?不在gcc的官方文件中(对于共享LIB也不准确):
链接时搜索名为library的库。(将库作为单独参数的第二个备选方案仅用于POSIX合规性,不推荐使用。)。。。使用-l选项和指定文件名之间的唯一区别是-l用“lib”和“.a”包围库,并搜索多个目录
binutils ld文档对此进行了描述。-lname
选项将搜索libname.so
,然后搜索libname.a
添加lib前缀和.so
(如果此时启用)或.a
后缀。但是-l:name
选项只会精确搜索指定的名称:
将namespec
指定的存档或对象文件添加到
要链接的文件。此选项可以使用任意次数。如果
namespec
的格式为:filename
,ld将搜索库路径
对于名为filename
的文件,否则将搜索库路径
对于名为libnamespec.a
的文件
在支持共享库的系统上,ld还可以搜索
libnamespec.a以外的文件
。特别是在ELF和SunOS上
系统,ld将搜索一个名为
libnamespec.so
在搜索名为libnamespec.a的文件之前。(由
约定,一个。因此
扩展名表示一个共享库。)注意
此行为不适用于始终指定
文件名为filename
Th
gcc -o test test.c -ldl "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libpthread.a"
gcc objectfiles -o program -Wl,-Bstatic -ls1 -ls2 -Wl,-Bdynamic -ld1 -ld2
-llibrary
-l library
-l namespec
--library=namespec