@@ -7,19 +7,155 @@ aside: true
7
7
## Description
8
8
待补充
9
9
10
- gcc -install_name @rpath/libutil .dylib -fPIC -shared -o src/dyn-util/libutil.dylib src/dyn-util/util.c
10
+ ## 动态链接和静态链接
11
+ ### 静态库
12
+ ::: code-group
13
+ ``` c [src/static-util/util.c]
14
+ #include " ./util.h"
15
+ #include " stdio.h"
11
16
12
- 在 macOS 系统上,动态链接库的搜索路径有一定的优先级排序。搜索逻辑和优先级如下:
13
- ** @executable_path** :首先搜索可执行文件所在的目录。
14
- ** @loader_path** :其次搜索加载该动态库的库所在的目录。
15
- ** @rpath ** :然后搜索运行路径(rpath),可以在编译时或运行时指定。
16
- ** DYLD_LIBRARY_PATH** :接着搜索由 DYLD_LIBRARY_PATH 环境变量指定的目录。
17
- ** DYLD_FALLBACK_LIBRARY_PATH** :如果前面的路径都没有找到,则搜索 DYLD_FALLBACK_LIBRARY_PATH 环境变量指定的目录。默认值为 /usr/local/lib 和 /usr/lib。
18
- 系统默认路径:最后搜索系统默认的库路径,如 /usr/lib
17
+ void hello () {
18
+ printf ("hello friends\n");
19
+ }
20
+
21
+ int find (const char* source, char dest) {
22
+ for ( int i = 0; source[ i] != '\0'; i++) {
23
+ if (source[ i] == dest) return i;
24
+ }
25
+ return -1;
26
+ }
27
+
28
+ ```
29
+
30
+ ```c [src/static-util/util.h]
31
+ #ifndef __My_Util
32
+ #define __My_Util
33
+ void hello();
34
+ int find(const char* source, char dest);
35
+ #endif
36
+ ```
37
+
38
+ ``` c [src/main.c]
39
+ #include < util.h>
40
+ #include < stdio.h>
41
+
42
+
43
+ int main () {
44
+ hello ();
45
+ int index = find("Jack", 'c');
46
+ if (index != -1) {
47
+ printf("index: %d\n", index);
48
+ }
49
+ }
50
+ ```
51
+ :::
52
+
53
+ 生成静态库:
54
+ ``` shell
55
+ gcc -c src/static-util/util.c -o src/static-util/util.o
56
+ ar r libutil.a src/static-util/util.o
57
+ ```
58
+ > 在 unix 上静态文件 .a 后缀,在Windows是.lib后缀
59
+ > 文件名是 lib{静态库名}
60
+
61
+ 使用静态库:
62
+ ``` shell
63
+ gcc -o main -I " src/static-util" -L " src/static-util" -lutil src/main.c && ./main
64
+
65
+ # 或者
66
+ gcc -o main -I " src/static-util" src/main.c src/static-util/libutil.a && ./main
67
+ ```
68
+ > -I 指定` include <a.h> ` 的时候,到哪个文件夹去找` a.h ` 文件
69
+ > -L 指定 寻找静态库的时候,到哪个文件夹去找
70
+ > -l 指定静态库文件名,此时lib和.a后缀可省略
71
+
72
+ ### 动态库
73
+ ::: code-group
74
+ ``` c [src/dyn-util/util.c]
75
+
76
+ #include " ./util.h"
77
+ #include " stdio.h"
78
+
79
+ void hello () {
80
+ printf ("hello friends\n");
81
+ }
19
82
20
- 生成动态链接库时,默认的注册名时./libutil.dylib, 但不知道为什么,macOS平台中,dyld使用可执行程序的当前工作目录或者DYLD_LIBRARY_PATH环境变量指定的目录,作为这个相对路径的参考目录,使用gcc -Wl.-rpath设置的动态链接库搜索目录将无效。为了解决这个问题,你要设置 -install_name, 告诉dyld,动链接库是rpath目录下的libutil.dylib文件
83
+ int find (const char* source, char dest) {
84
+ for ( int i = 0; source[ i] != '\0'; i++) {
85
+ if (source[ i] == dest) return i;
86
+ }
87
+ return -1;
88
+ }
89
+
90
+ ```
91
+
92
+ ```c [src/dyn-util/util.h]
93
+ #ifndef __My_Util
94
+ #define __My_Util
95
+ void hello();
96
+ int find(const char* source, char dest);
97
+ #endif
98
+ ```
99
+
100
+ ``` c [src/main.c]
101
+ #include < util.h>
102
+ #include < stdio.h>
103
+
104
+
105
+ int main () {
106
+ hello ();
107
+ int index = find("Jack", 'c');
108
+ if (index != -1) {
109
+ printf("index: %d\n", index);
110
+ }
111
+ }
112
+ ```
113
+ :::
114
+
115
+ 生成动态库:
116
+ ``` shell
117
+ gcc -fPIC -shared -o src/dyn-util/libutil.dylib src/dyn-util/util.c
118
+ ```
119
+ > 动态链接库名格式为 lib{库名}.{后缀};
120
+ > linux的后缀是 so;
121
+ > Mac的后缀是 dylib;
122
+ > Windows的后缀是 dll;
123
+ > -fPIC 中 PIC的含义是` Position Independent Code ` ;
124
+
125
+ 使用动态库:
126
+ ``` shell
127
+ gcc -I " src/dyn-util" -L " src/dyn-util" -lutil -Wl,-rpath,$PWD /src/dyn-util -o main src/main.c && ./main
128
+ ```
129
+ > -Wl, -rpath, $PWD/src/dyn-util 指定动态连接器的搜索路径,可以阅读[ rust编译出来的executable file比cpp大] ( /blog/rust-binary-is-big )
130
+
131
+ 如果你将上边生成的main文件移动到别的目录下,并在该目录下执行,就会报错,错误大致的意思是找不到动态链接库:
132
+ ``` shell
133
+ cp main src/main
134
+ cd src
135
+ ./main
136
+ ```
137
+ 解决方法是,改用下边的指令生成动态链接库:
138
+ ``` shell
139
+ gcc -install_name @rpath/libutil.dylib -fPIC -shared -o src/dyn-util/libutil.dylib src/dyn-util/util.c
140
+ ```
141
+
142
+ 生成动态链接库时,默认的注册名时./libutil.dylib, 但不知道为什么,macOS平台中,dyld使用可执行程序的当前工作目录或者DYLD_LIBRARY_PATH环境变量指定的目录,作为这个相对路径的参考目录,使用gcc -Wl.-rpath设置的动态链接库搜索目录将无效。为了解决这个问题,你要设置 -install_name, 告诉dyld,动链接库是rpath目录下的libutil.dylib文件.
21
143
22
144
-install_name是macOS特有的配置项,在 Linux 上,类似的功能可以通过 -soname 选项来实现:
23
145
``` shell
24
146
gcc -shared -o libexample.so.1.0 source.c -Wl,-soname,libexample.so.1
25
- ```
147
+ ```
148
+
149
+ :::tip <TipIcon />
150
+ 在 macOS 系统上,动态链接库的搜索路径有一定的优先级排序。搜索逻辑和优先级如下:
151
+ 1 . ** @executable_path** :首先搜索可执行文件所在的目录。
152
+ 2 . ** @loader_path** :其次搜索加载该动态库的库所在的目录。
153
+ 3 . ** @rpath ** :然后搜索运行路径(rpath),可以在编译时或运行时指定。
154
+ 4 . ** DYLD_LIBRARY_PATH** :接着搜索由 DYLD_LIBRARY_PATH 环境变量指定的目录。
155
+ 5 . ** DYLD_FALLBACK_LIBRARY_PATH** :如果前面的路径都没有找到,则搜索 DYLD_FALLBACK_LIBRARY_PATH 环境变量指定的目录。默认值为 /usr/local/lib 和 /usr/lib。
156
+ 6 . 系统默认路径:最后搜索系统默认的库路径,如 /usr/lib
157
+ :::
158
+
159
+ ## 查看可执行程序
160
+
161
+ ## 调试可执行程序
0 commit comments