动态库与静态库
构建静态库:
gcc -o mylib.o -c mylib.c
# 要构建静态库,请使用归档器 (`ar`):
ar -rcs libmylib.a mylib.o
构建动态库:
gcc -fPIC -o mylib.o -c mylib.c
gcc -shared -o libmylib.so mylib.o
linux 混合使用动态库与静态库
如果混合使用静态库和静态库. 动态库使用 -lxxx (也就是libxxx.so文件), 静态库直接将 .o 或者 .a 文件放在命令选项中.
gcc myprog.c -L. -Wl,-Bdynamic -lc libmylib.a
gcc myprog.c -L. -Wl,-Bdynamic -lc -l:libmylib.a
目前, 在 ubuntu 22.04 上, -Bstatic 似乎无法被 ld 执行, 缺少 -lgcc_s 动态库.
$ gcc myprog.c -L. -Wl,-Bdynamic -lc -Wl,-Bstatic -lmylib
/usr/bin/ld: 找不到 -lgcc_s: 没有那个文件或目录
/usr/bin/ld: 找不到 -lgcc_s: 没有那个文件或目录
collect2: error: ld returned 1 exit status
$ gcc myprog.c -L. -Wl,-Bstatic -lmylib
/usr/bin/ld: 找不到 -lgcc_s: 没有那个文件或目录
/usr/bin/ld: 找不到 -lgcc_s: 没有那个文件或目录
collect2: error: ld returned 1 exit status
- 方法1: -l 默认优先链接动态库, 如果要链接静态库,请指定
-l:libxxx.a
即可. 或者直接在命令行使用 libxxx.a 文件即可. 方法2: 使用-Wl,-Bstatic -lxxx 链接静态库
gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond ...
这个命令使用静态链接链接 first 库, 使用动态链接链接 second 库.
$ gcc myprog.c -L. -Wl,-Bstatic -lmylib
$ ldd a.out
linux-vdso.so.1 (0x00007ffca859d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000717456000000)
/lib64/ld-linux-x86-64.so.2 (0x0000717456420000)
$ ./a.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
windows 混合使用动态库与静态库
windows上可以运行:
$ gcc myprog.c -L. -l:libmylib.a
$ gcc myprog.c -L. -Wl,-Bstatic -l:libmylib.a
$ gcc myprog.c -L. -Wl,-Bstatic -lmylib
$ gcc myprog.c -L. -lmylib
$ ./myprog.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
这个windows上无法执行.
$ gcc myprog.c -lc -L. -l:libmylib.a
$ ldd a.out
linux-vdso.so.1 (0x00007ffca859d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000717456000000)
/lib64/ld-linux-x86-64.so.2 (0x0000717456420000)
$ ./a.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
完全静态链接
将整个可执行文件静态编译:
$ gcc myprog.c -lmylib -L. -static
$ ldd a.out
不是动态可执行文件
$ readelf -d a.out
There is no dynamic section in this file.
$ ./a.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
python wheel musl
manylinux 支持新的 musl libc.
PEP 656 – Platform Tag for Linux Distributions Using Musl
Wheels for musl (Alpine)
gcc && ld
gcc docs
GNU linker ld (GNU Binutils)
ELF
ELF: From The Programmer's Perspective
hacker news ELF: From The Programmer's Perspective
Notes on the Flat-Text Transcription
ELF_Format
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux
“Shared libraries are not a good thing in general”
静态库与动态库
pdf: Red Hat Enterprise Linux 7 Developer Guide
html: Red Hat Enterprise Linux 7 Developer Guide
可以翻译这个文档:
Program Library HOWTO
符号链接
GCC 共享库 - 强制导入依赖库中的符号
Use of shared library is good in c but same code is bad in c++?
gcc -fPIC
静态库, 动态库与 -fPIC 编译细节探索:
$ gcc -o mylib.o -c mylib.c
$ ar -rcs libmylib.a mylib.o
$ gcc myprog.c -lmylib -L.
$ ./a.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
静态库使用 -fPIC 也可以运行, 有什么区别?
$ gcc -fPIC -o mylib.o -c mylib.c
$ ar -rcs libmylib.a mylib.o
$ gcc myprog.c -lmylib -L.
$ ./a.out
Enter two float values: 1
2
1.000000 and 2.000000
2.000000 is the biggest
编译动态库不使用 -fPIC 会有明确的错误提示:
$ gcc -o mylib.o -c mylib.c
$ gcc -shared -o libmylib.so mylib.o
/usr/bin/ld: mylib.o: warning: relocation against `total_times' in read-only section `.text'
/usr/bin/ld: mylib.o: relocation R_X86_64_PC32 against symbol `total_times' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
动态库的正确使用模式:
$ gcc -fPIC -o mylib.o -c mylib.c
$ gcc -shared -o libmylib.so mylib.o
libc
C_standard_library Implementations
Writing C software without the standard library
forcing-elf-binary-to-use-another-libc-so
Multiple glibc libraries on a single host
how-to-run-new-software-without-updating-glibc
how-to-chroot-to-provide-a-new-glibc-version-to-an-app
glibc-improvements-and-what-to-expect-in-future-linux-distributions
https://news.ycombinator.com/item?id=29479769
glibc
glibc backward compatibility
how-the-gnu-c-library-handles-backward-compatibility how-compatible-are-different-versions-of-glibc ABI_checker Creating and using chroots and containers
Dynamically load library from chroot with glibc dependency
chroot
obtain libc version
ldd
root@ub18:~# ldd --version | head -n1
ldd (Ubuntu GLIBC 2.27-3ubuntu1.6) 2.27
features.h
GCC_FEATURES=$(gcc -dM -E - <<< "#include <features.h>")
if grep -q __UCLIBC__ <<< "${GCC_FEATURES}"; then
echo "uClibc"
grep "#define __UCLIBC_MAJOR__" <<< "${GCC_FEATURES}"
grep "#define __UCLIBC_MINOR__" <<< "${GCC_FEATURES}"
grep "#define __UCLIBC_SUBLEVEL__" <<< "${GCC_FEATURES}"
elif grep -q __GLIBC__ <<< "${GCC_FEATURES}"; then
echo "glibc"
grep "#define __GLIBC__" <<< "${GCC_FEATURES}"
grep "#define __GLIBC_MINOR__" <<< "${GCC_FEATURES}"
else
echo "something else"
fi
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
How to update libc version on major Linux distros
In case you find your installed libc
to be out of date, it is simple enough to bring it up to date on any Linux system.
You can use the appropriate command below to update libc with your system’s package manager.
To update libc on Ubuntu, Debian, and Linux Mint:
$ sudo apt update
$ sudo apt install libc-bin
To update libc on Fedora, CentOS, AlmaLinux, and Red Hat:
$ sudo dnf install glibc
To update libc on Arch Linux and Manjaro:
$ sudo pacman -Syu glibc
link to glibc version
How can I specify the GLIBC version in cargo build for Rust?
static link
glibc heap
Arm Heap Exploitation
UNDERSTANDING THE GLIBC HEAP IMPLEMENTATION
asm
x86_64
System Calls On x86_64 from User Space
编译链接参考资料
https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
https://www.akkadia.org/drepper/dsohowto.pdf
-fPIC
Why does gcc not implicitly supply the -fPIC flag when compiling static libraries on x86_64
What, if any, are the implications of compiling objects with gcc -fPIC flag if they get used in executables?
Is -fPIC implied on modern platforms
Is -fPIC for shared libraries ONLY?
Does one still need to use -fPIC when compiling with GCC?
What does -fPIC mean when building a shared library?
What is the -fPIE option for position-independent executables in gcc and ld?
How can I tell, with something like objdump, if an object file has been built with -fPIC?
https://stackoverflow.com/questions/1340402/how-can-i-tell-with-something-like-objdump-if-an-object-file-has-been-built-wi
runpath
https://ziggit.dev/t/why-zig-adds-dynamic-library-path-into-final-executable/4688