副标题——自定义c文件的链接问题
本文章是我调试整个过程,直到最后才解决问题。我不大记得make写法,所以makefile改了好多次。
/tmp/ccNOjiLG.o: In function `main':
test_for_print_tree.c:(.text+0x15): undefined reference to `init_queue'test_for_print_tree.c:(.text+0x25): undefined reference to `ifEmpty'
test_for_print_tree.c:(.text+0x5c): undefined reference to `creatTree'
test_for_print_tree.c:(.text+0x8b): undefined reference to `print_tree'
是因为多个文件之间缺少链接关系。
我定义了tree.h tree.c queue.h queue.o print_tree.h print_tree.c等好多文件,之间用include联系,貌似因为没有编译出各自的.o文件,所以链接出错。看来要用make把各个依赖文件组织起来。
我写了个Makefile后,解决了, 内容为
main.o : build_tree.o print_tree.o queue.o tree.o
gcc -c test_for_print_tree.c -o main.o
build_tree.o: build_tree.h build_tree.c
gcc -c build_tree.c -o build_tree.o
print_tree.o: print_tree.h print_tree.c
gcc -c print_tree.c -o print_tree.o
queue.o: queue.h queue.c
gcc -c queue.c -o queue.o
tree.o: tree.h tree.c
gcc -c tree.c -o tree.o
要注意,gcc前是tab空格,不能用空格代替,否则报错如下:
Makefile:2: *** missing separator. Stop.
编译结果
norton@norton-laptop:~/learning/sample code/tree/reconstruct$ make main.o
gcc -c tree.c -o tree.o
gcc -c test_for_print_tree.c -o main.o
通过了!
但是运行时发现了如下错误
norton@norton-laptop:~/learning/sample code/tree/reconstruct$ chmod 777 main.o
norton@norton-laptop:~/learning/sample code/tree/reconstruct$ ./main.o
bash: ./main.o: cannot execute binary file
这是因为上面的Makefile在编译main时,加入了-c参数,这个是编译成库,意思是编译/汇编/但不链接。
修改Makefile为
main.o : build_tree.o print_tree.o queue.o tree.o
gcc test_for_print_tree.c -o main.o
build_tree.o: build_tree.h build_tree.c
gcc -c build_tree.c -o build_tree.o
print_tree.o: print_tree.h print_tree.c
gcc -c print_tree.c -o print_tree.o
queue.o: queue.h queue.c
gcc -c queue.c -o queue.o
tree.o: tree.h tree.c
gcc -c tree.c -o tree.o
出现如下错误,因为我没有删掉之前的.o文件。
make: `main.o' is up to date
因此我在Makefile里面加入clean目标
clean :
rm *.o
然后make clean清理.o文件。
重新make一次,发现问题依旧
norton@norton-laptop:~/learning/sample code/tree/reconstruct$ make main.o
gcc -c build_tree.c -o build_tree.o
gcc -c print_tree.c -o print_tree.o
gcc -c queue.c -o queue.o
gcc -c tree.c -o tree.o
tree.c: In function ‘init_TNode’:
tree.c:5: warning: incompatible implicit declaration of built-in function ‘malloc’
tree.c:7: error: ‘NULL’ undeclared (first use in this function)
tree.c:7: error: (Each undeclared identifier is reported only once
tree.c:7: error: for each function it appears in.)
make: *** [tree.o] Error 1
原来gcc编译库的办法是把依赖的.o文件直接加在执行文件后,所以我把main.o的操作改为:
main.o : test.o build_tree.o print_tree.o queue.o tree.o
gcc -o main.o test.o build_tree.o print_tree.o queue.o tree.o
编译通过,结果出来了!
以上的写法,之间在linux内核见过多次,也学过,就是记不住,只有亲身经历,才有深刻体会。