gpt4 book ai didi

c - 这些不同的 gcc 链接选项如何改变最终的可执行文件?

转载 作者:太空宇宙 更新时间:2023-11-04 07:24:01 24 4
gpt4 key购买 nike

我想了解 gcc 中的库和链接是如何工作的。我正在尝试编译 an example ncurses 来自文件 test.c 的“Hello World”程序:

#include <ncurses.h>

int main()
{
initscr(); /* Start curses mode */
printw("Hello World !!!"); /* Print Hello World */
refresh(); /* Print it on to the real screen */
getch(); /* Wait for user input */
endwin(); /* End curses mode */

return 0;
}

我首先使用以下命令编译它(没有生成文件):

gcc test.c -o test.exe -lncurses

这产生了一个 9kb 的文件。在不了解 -lncurses 开关的作用之后,我阅读了一些有关链接的内容,然后阅读了有关静态和动态的内容,并决定我想尝试静态编译 la here :

gcc -static test.c -o test.exe -lncurses

但是,出于某种原因,这不起作用,并产生了大量的 ld 'undefined reference to x' 错误。示例:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libncurses.a(lib_echo.o): In function `echo':
(.text+0x3): undefined reference to `SP'

从其他地方,我添加了一个 -L/usr/lib 选项:

gcc -static test.c -o test.exe -L/usr/lib -lncurses

这创建了一个更大的文件,1103kb。
我能理解为什么它应该更大。我不明白的是为什么只删除 -static 选项:

gcc test.c -o test.exe -L/usr/lib -lncurses

... 生成一个大小为 184kb 的文件,即使它没有静态链接到 ncurses 库。

-L/usr/lib 选项在这里做什么?根据online docs ,它将目录“添加到要搜索的目录列表中 -l”。/usr/lib 目录有一个 libncurses.a 文件(除其他外),而/usr/include 包含一个 ncurses.h 符号链接(symbolic link)到 curses.h 和一个 ncurses_dll.h。也许libncurses.a 文件不是 动态库?那么 ncurses.h 是什么?

最佳答案

这很可能是您想要构建它的方式:

gcc test.c -o test -lncurses

这表示:“编译 test.c,将输出文件命名为 test 并动态链接名为 libncurses.so 的库(或共享对象)(自动添加 lib 前缀)。

请注意 .exe后缀未在 Linux 上使用,仅在 Windows 上使用(您的问题带有 linux 标记,因此我假设这是您在此处使用的平台)。

如果你像这样静态链接:

gcc -static test.c -o test.exe -lncurses

然后链接器将查找库的静态版本(即 libncurses.a )。您会遇到一大堆链接器错误,因为它无法解析对库函数的引用,这表明您没有库的静态版本。除非您有充分的理由进行静态链接,否则通常使用动态链接。

下一个命令只是指定了一些额外的(但冗余的)库路径:

gcc -static test.c -o test.exe -L/usr/lib -lncurses

这只是告诉链接器在 /usr/lib 中搜索寻找图书馆时。然而,/usr/lib已经在默认路径中,所以这通常不会有什么不同。如果你运行 gcc -dumpspecs它将打印所有已“融入”工具的路径和定义,以及包含文件、库等的默认搜索路径。

The /usr/lib directory has a libncurses.a file (amongst others) while the /usr/include contains a an ncurses.h symlinked to curses.h and an ncurses_dll.h. Is perhaps the libncurses.a file not a dynamic library? What is ncurses.h then?

存在符号链接(symbolic link)是为了向后兼容。 ncurses图书馆(“新诅咒”)取代原来的curses , 但提供 curses.h所以旧代码仍然可以构建和运行。 ncurses_dll.h header 提供了一些仅用于windows下cygwin或MSVC编译的定义,可以忽略。 ncurses.h是库的真正主要 header ,应该用于新代码。

关于c - 这些不同的 gcc 链接选项如何改变最终的可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19645152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com