C - 手动编译并与 make 链接后"File or folder not found"



我们有一个创建makefile的练习,它应该"创建一个项目bbfooBBFOOBarbazFoo链接。巴尔巴兹与巴尔巴兹相连。使用编译器 cc(在我的系统上是 gcc(和链接器 ld。

我创建了三个简单的 c 文件:

酒吧:

int one() {
return 1;
}

baz.c:

int two() {
return 2;
}

福克

#include <stdio.h>
int main() {
printf("bar: %dn", one());
printf("baz: %dn", two());
return 0;
}

和以下生成文件:

bar: bar.c
cc -c -g -o bar.o bar.c
baz: baz.c
cc -c -g -o baz.o baz.c
barbaz: bar baz
ld -shared -o barbaz.o bar.o baz.o
foo: foo.c
cc -c -g -Wno-implicit-function-declaration -o foo.o foo.c
bbfoo: barbaz foo
ld -lc --entry=main -o bbfoo.out barbaz.o foo.o

$ 制作 bbfoo

工作没有错误,并创建了相应的文件。但是当我尝试运行该项目时

$ ./bbfoo.out

它显示"找不到文件或文件夹"。

当我使用 gcc 时,它完美无缺:

$ gcc -o bbfoo.out bar.c baz.c foo.c

$ ./bbfoo.out

酒吧: 1

巴兹: 2

我的错误是什么?甚至可以链接这样的项目(分两步(吗?

生成文件使用ld进行链接,但gcc示例使用编译器驱动程序进行链接。你也应该这样做:

bbfoo: barbaz foo
gcc -o bbfoo.out barbaz.o foo.o

编译器驱动程序可能(在您的情况下显然确实(包含一堆特定于系统的东西,使您的程序实际工作。通常不建议尝试直接运行链接器。

如果你想看看它真正使用的链接行是什么,你可以使用 GCC 的-v标志,如果你愿意,也可以将标志从中复制到你的 makefile 中。但是,您将来就有可能无法接受重要的更改。

如果你使用make,你应该坚持它的基本原则,我们可以总结为:

FILE-to-create: files-used-to-create-FILE
shell-commands-that-create-FILE

这非常重要,因为 make 比较文件的上次修改时间以确定哪些是过期的,哪些是最新的。这不是一种形式,它确实改变了功能。因此,在您的情况下,您应该拥有:

bar.o: bar.c
cc -c -g -o bar.o bar.c
baz.o: baz.c
cc -c -g -o baz.o baz.c
foo.o: foo.c
cc -c -g -Wno-implicit-function-declaration -o foo.o foo.c
barbaz.so: bar.o baz.o
ld -shared -o barbaz.so bar.o baz.o
bbfoo: barbaz.so foo.o
ld -lc --entry=main -o bbfoo barbaz.so foo.o

请注意,make 有一些不错的功能,可以帮助分解这种简单的规则集。例如,自动变量($@$^...(,隐式规则(例如,用于从*.c源文件构建*.o对象文件(,隐式规则使用的隐式变量(CFLAGSLD...(,特定于目标的变量值(查看foo.oCFLAGS声明(等等。例:

CFLAGS := -g
foo.o: CFLAGS += -Wno-implicit-function-declaration
barbaz.so: bar.o baz.o
$(LD) -shared -o $@ $^
bbfoo: barbaz.so foo.o
$(LD) -lc --entry=main -o $@ $^

是的,目标文件根本没有规则,make 已经知道如何构建它们。

发布的代码包含很多缺点。

建议:

酒吧.H

#ifndef BAR_H
#define BAR_H
int one( void );
#endif

酒吧:

#include "bar.h"
int one() {
return 1;
}

巴兹·

#ifndef BAZ_H
#define BAZ_H
int one( void );
#endif

baz.c:

#include "baz.h"
int two() {
return 2;
}

福克

#include <stdio.h>
#include "bar.h"
#include "baz.h"
int main( void ) {
printf("bar: %dn", one());
printf("baz: %dn", two());
return 0;
}

makefile.mak

.PHONY all
all: bbfoo.out
bar: bar.c bar.h
cc -c -g -o bar.o bar.c -Ibar.h
baz: baz.c baz.h
cc -c -g -o baz.o baz.c -Ibaz.h
libbarbaz.so: baz.o bar.o
ld -shared -o libbarbaz.so bar.o baz.o    
foo: foo.c baz.h bar.h
cc -c -g -Wno-implicit-function-declaration -o foo.o foo.c -Ibar.h -Ibaz.h
bbfoo.out:  foo.o libbarbaz.so
ld -lc --entry=main -o bbfoo.out foo.o -lbarbaz

使用make中找到的快捷方式变量将大大缩短此生成文件,但会使其更加神秘

相关内容

  • 没有找到相关文章

最新更新