GCC编译和链接

3
我用以下方式创建了一个共享库:

(我)创建了一个共享库

gcc -I/home/lib 'pkg-config --cflags gtk+-2.0 libxml-2.0' -shared -fPIC -Wl,--export-dynamic file1.c file2.c -o lib.so

它可以工作,创建的库也能满足我的需求。 我想知道的是编译和链接在这个命令字符串中的位置,所以请向我解释并告诉我一种将它们分为两个不同命令的方法,以便更好地理解。 我需要理解这个,因为我无法解释为什么这个库可以工作,即使它必须链接到另一个我从未链接过的库。


1
通过您展示的命令,前端程序gcc调用编译器和链接器作为一个整体。或者您是想知道哪些命令行选项和标志是特定于编译、链接以及两者共同使用的? - Some programmer dude
你不需要链接任何东西。 - 0___________
1
@P__J__ 共享库的链接方式与可执行程序相同。 - Some programmer dude
是的,我想知道哪些命令行选项和标志是用于编译、链接或者两者都共用的。 - user10207893
1
“-Wl,”是链接器命令选项的起点,其中你将“--export-dynamic”作为单个链接器选项。这告诉 gcc 使用显示的编译器选项(以及从调用 pkg-config 生成的选项)来编译文件,然后使用链接器选项“--export-dynamic”调用链接器。加上-v以获得详细输出,例如gcc -v ...,您将看到编译和链接所需的所有内容。与简单的汇编程序不同,您需要链接C运行时库,需要执行更多操作才能将其编译为目标文件,并简单地调用 ld 将其链接到可执行文件中。 - David C. Rankin
显示剩余4条评论
3个回答

5

您的命令一次性完成编译和链接。

您可以将命令拆分为编译和链接两个步骤:

gcc -c -o file1.o -Wall -Wextra -Werror -I/home/lib $(pkg-config --cflags gtk+-2.0 libxml-2.0) -fPIC file1.c
gcc -c -o file2.o -Wall -Wextra -Werror -I/home/lib $(pkg-config --cflags gtk+-2.0 libxml-2.0) -fPIC file2.c
gcc -shared -o lib.so file1.o file2.o

4
GCC使用文件名中的扩展名来确定它们的类型和处理方式。因此,您列出一些以“.c”结尾的名称告诉GCC将它们编译为C代码。如果您只给出以“.o”结尾的名称,GCC会将它们视为目标文件,并不会对它们进行编译。
编译后,默认情况下,GCC会链接生成可执行文件。使用“-shared”开关会告诉它生成共享库而不是可执行文件。
要仅编译而不链接,可以使用开关“-c”,并删除“-shared”开关,还要删除任何仅用于链接的命令参数或开关(例如“-Wl,--export-dynamic”),我不知道pkg-config是否会产生任何链接选项。还要删除或更改“-o lib.so”,因为这会设置用于仅编译时生成的目标文件的输出文件名,而这不是您想要的。
要仅链接而不编译,您只需列出目标文件而不是源文件,并删除影响编译的开关(例如“-I/home/lib”、“-fPIC”以及由pkg-config生成的任何开关)。

现在这是一个很好的答案。我不知道GCC使用扩展来区分任务。 - polkovnikov.ph

2
gcc -c 选项是只编译不链接。但是,我不确定这是否符合您的要求。

这应该是一条注释,而不是一个答案。 - L_J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接