Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无法创建链接静态库的可执行文件_C_Linux_Ubuntu_Linker - Fatal编程技术网

C 无法创建链接静态库的可执行文件

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

在文件夹测试中,我创建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("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