C 无法创建链接静态库的可执行文件
在文件夹测试中,我创建hello.h、hello.c、main.c。 我的目标是从hello.h、hello.c创建一个静态库,并从库和main.c创建一个可执行文件。 以下是我所做的 你好,h:C 无法创建链接静态库的可执行文件,c,linux,ubuntu,linker,C,Linux,Ubuntu,Linker,在文件夹测试中,我创建hello.h、hello.c、main.c。 我的目标是从hello.h、hello.c创建一个静态库,并从库和main.c创建一个可执行文件。 以下是我所做的 你好,h: #ifndef HELLO_H #define HELLO_H void hello(const char* name); #endif 你好,c: #include <stdio.h> void hello(const char* name){ printf
#ifndef HELLO_H
#define HELLO_H
void hello(const char* name);
#endif
你好,c:
#include <stdio.h>
void hello(const char* name){
printf("hello %s! \n",name);
}
在终端的测试文件夹中:I run
gcc -c hello.c
ar crv libmyhello.a hello.o // to create a staticlib
gcc -c main.c
ld -o Cuteee hello.o -lmyhello
>>> ld: cannot find -lmyhello
我想知道是否有什么问题?您需要提供-L以让gcc知道在哪里可以找到您的-L库:
gcc -c hello.c
ar crv libmyhello.a hello.o
gcc -c main.c
gcc main.o -L. -lmyhello -o Cuteee
要创建最终的可执行文件,使用gcc就足够了,不需要ld
请参阅,以了解您可能不需要特别使用ld的原因。以下建议代码: 更正了发布的代码和命令行语句中的几个问题。 执行所需的操作 干净地编译/链接 现在建议对发布的代码和命令行语句进行更改:
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello( const char* );
#endif
=======================
hello.c:
#include <stdio.h>
#include "hello.h"
void hello(const char* name)
{
printf("hello %s! \n",name);
}
========================
main.c:
#include "hello.h"
int main( void )
{
hello("everyone");
return 0;
}
=========================
In terminal (in test folder):
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c hello.c -o hello.o -I.
ar crv libmyhello.a hello.o
=========================
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c main.c -o main.o -I.
ld -static main.o -o Cuteee -L. -lmyhello
=========================
./Cuteee
=========================
this should eliminate the error message:
>>> ld: cannot find -lmyhello
这考虑了您的意见: 然后我尝试了ld-o-Cuteee-main.o-L-lmyhello,但仍然失败了:警告:找不到入口符号_start;默认值为0000000000 4000b0./libmyhello.ahello.o:在函数“hello”中:hello.c:.text+0x1e:对“printf”的未定义引用我再次感到困惑 gcc是用于编译和链接C程序的gcc工具驱动程序 当您使用表示要编译C的选项和输入调用它时 源文件say hello.c,它首先调用GNUC编译器cc1来编译hello.c 文件转换为临时程序集文件,例如/tmp/cc8bfSqS.s。它悄悄地添加到编译器命令行中 编译C时不变的各种样板选项 在你的系统上,省去你的麻烦 然后它调用GNU汇编程序as,将/tmp/cc8bfSqS.s汇编到对象文件中 你好,o 如果要求gcc详细,您可以从编译输出中找出所有这些内容, e、 g 当您使用表示要链接的选项和输入调用gcc时 将文件和库(可能是库)装入程序或共享库, 它调用GCC内部工具来完成这项工作-这 反过来调用系统链接器ld,gcc悄悄地添加到命令行中 许多样板文件选项、库和对象文件 需要将C语言程序或共享库再次链接到 省事吧 您已经使用gcc编译了hello.c和main.c,并允许它正确地运行 幕后的事情。您还没有尝试调用cc1和as您自己 但与此相反,当你链接你的程序时,你没有使用gcc;你已经 自己调用ld,而不向 gcc将使用的命令行。这就是链接失败的原因 如果在详细模式下将程序与gcc链接:
gcc -v -o Cuteee main.o -L. -lhello
您可以从输出中选择collect2命令行,例如:
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 \
-plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so \
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper \
-plugin-opt=-fresolution=/tmp/ccgWPdno.res \
-plugin-opt=-pass-through=-lgcc \
-plugin-opt=-pass-through=-lgcc_s \
-plugin-opt=-pass-through=-lc \
-plugin-opt=-pass-through=-lgcc \
-plugin-opt=-pass-through=-lgcc_s \
--sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu \
--as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
-pie -z now -z relro -o Cuteee \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o \
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L. \
-L/usr/lib/gcc/x86_64-linux-gnu/7 \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib \
-L/lib/x86_64-linux-gnu -L/lib/../lib \
-L/usr/lib/x86_64-linux-gnu \
-L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. \
main.o -lhello -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc \
--as-needed -lgcc_s --no-as-needed \
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
传递给collect2的所有选项都传递给
劳埃德。因此,如果将/usr/lib/gcc/x86_64-linux-gnu/7/collect2替换为
在怪物的命令行中,或者更确切地说,在你的命令行中
在您自己的系统中,您会发现它链接了您的程序。/Cuteee
这就是将程序与gcc链接在一起所做的工作,在上面:
ld -o Cuteee hello.o -lmyhello
链接尝试失败的错误之一:
cannot find entry symbol _start
是因为您没有链接Scrt1.o/usr/lib/x86_64-linux-gnu/Scrt1.o,
在上面的命令行中,该命令行包含
动态链接的C程序:它定义符号_start,其地址是程序的入口点,
加载程序在运行时和程序初始化后向其传递初始控制
完成后,它调用main
另一个悬挂机构错误:
undefined reference to 'printf
是因为您没有链接标准C库,-lc
/lib/x86_64-linux-gnu/libc.so.6
如果程序员不必直接与ld链接,他们就不会直接与ld链接。
除非他们将应用程序定位于裸机环境
我知道原因。但是我很好奇如何在这里使用ld,尽管gcc更好。然后我尝试了ld-o-Cuteee-main.o-L-lmyhello,但仍然失败了:警告:找不到入口符号_start;默认值为0000000000 4000b0./libmyhello.ahello.o:在函数“hello”中:hello.c:.text+0x1e:未定义对“printf”的引用我再次感到困惑。printf来自libc库,因此您可能还需要使用-lc链接到它。文件:hello.c需要包含以下语句:include hello.h
cannot find entry symbol _start
undefined reference to 'printf