实验要求
- 在提供的虚拟机中编译Nachos3.4
- 通过Makefile熟悉项目结构
- 尝试添加一个源文件,并且成功编译
记录第3步,添加文件时出现的问题。
尝试在thread/
文件夹中添加一个test.h
与test.cc
文件。内容如下:
// test.h
#ifndef TEST_H
#define TEST_H
int add(int, int);
int test_h;
#endif
// test.cc
#include "test.h"
int add(int a, int b)
{
return a + b;
}
在main.cc
中修改,包含该文件,并且调用add
方法。
// main.cc
//...
#include "test.h"
//...
// line 82-84
int main(int argc, char **argv)
{
printf("int main add(1,2)=%dn", add(test_h, test_h));
...
}
修改对应的Makefile文件,分别是thread/Makefile
,Makefile.common
文件。
在thread/Makefile
文件中添加main.o
的依赖项。
main.o: ...# 已省略
../threads/test.h
对应的,在Makefile.common
文件中THREAD
相关的部分添加test.h
或test.cc
。
# Makefile.common
THREAD_H =../threads/copyright.h
...
../threads/test.h
..。
THREAD_C =../threads/main.cc
...
../threads/thread.cc
...
THREAD_O =main.o list.o scheduler.o synch.o synchlist.o system.o thread.o
utility.o threadtest.o interrupt.o stats.o sysdep.o timer.o test.o
编译:
vagrant@precise32:/vagrant/nachos/nachos-3.4/code$ make
可是出现了报错:
![5f271a6194158a5e7f459ac03314d24e.png](https://i-blog.csdnimg.cn/blog_migrate/fdd68b7c04a9abcf09cc3cc2fdf717ed.png)
出错阶段为ld
链接阶段,错误信息为test_h
出现了重复定义multiple definition
,可是实际上只定义了一次,这是为什么呢?
原来在编译期间,main.cc
与test.cc
均被编译成为了*.o
文件,test_h
的定义就保存在其中了。因此在链接阶段,就出现了重复定义错误。
解决办法:
在test.h
中将test_h
声明为全局extern
,具体定义在test.cc
中完成,这样就可以确保test_h
这个名称的唯一性了。
// test.h
#ifndef TEST_H
#define TEST_H
int add(int, int);
extern int test_h;
#endif
#include "test.h"
int test_h = 10;
int add(int a, int b)
{
return a + b;
}
再次编译项目,可以看到编译成功,运行nachos
文件,也能得到预期效果。
vagrant@precise32:/vagrant/nachos/nachos-3.4/code$ make
![aaa49a55113e9116c0b345c35941d048.png](https://i-blog.csdnimg.cn/blog_migrate/ec8174feeb25e33dae4978581f3ad34f.jpeg)
![bac3282f35030573a84021bceb0c79ba.png](https://i-blog.csdnimg.cn/blog_migrate/0c7e865fec403563a15b173fb4814a5a.jpeg)
总结
C语言中编译单个文件和编译整个项目的许多概念是非常不同的,首先是使用了Makefile来管理和组织文件,这样每次添加或删除源文件,都需要在Makefile中做出相应的修改,才能保证整个项目的正确编译。
其次还有变量名占用,条件编译等注意事项,这次遇到的问题也让我了解了extern
关键字的用法,对C项目编译链接等过程有了更深的认识。突然想到最开始学习编程和C语言时听到的一句话,感谢每一次编译器给出的错误信息,那都是学习和提高的好机会!
参考资料
https://blog.csdn.net/mantis_1984/article/details/53571758