编译中出错:提示没有 <SDL2/SDL.h>头文件
查看错误信息,出错的文件在abstract-machine文件夹里,叫input.c,里面引用了SDL2/SDL.h 这个头文件,但是我只在fceux文件夹里搜到了sdl.h,考虑到linux区分大小写,搜索以后,我觉得我应该是系统缺少了SDL库。
sudo apt install libsdl2-dev 安装以后编译通过,和fc文件夹的sdl.h没有关系。
然后运行make ARCH=native mainargs=k run,经过检查,按键没有问题。
在架构选择这一块,我倾向于x86和RISCV-64。时间有限的话,我更倾向于riscv.
ysyx项目文件架构:框架 官方文档 (oscc.cc)
nemu/include/generated/autoconf.h 这个文件是一些宏定义相关,nemu/include/config/auto.conf 这个文件是一些配置参数,大致是编译时要选择的编译参数。
make menuconfig打开完整选项
----------------------
插入一下编译c/c++的过程:
1. 预编译,ifdef这样的语句在这一步会被处理,头文件也会被引入。c++的话,constexpr标记的函数也会在这一步处理,生成.i文件
2. 编译 生成.s文件 ,对应即将代码变成汇编文件
3. 汇编 将上一步得到的汇编文件变为二进制文件 对应.o后缀
4. 链接 将.o文件与库链接,生成可执行的.exe文件
------------------
讲义里给出了makefile的规则:
$(OBJ_DIR)/%.o: %.c @echo + CC $< @mkdir -p $(dir $@) @$(CC) $(CFLAGS) -c -o $@ $< $(call call_fixdep, $(@:.o=.d), $@)
第一行表示 obj_dir 这个变量对应的目录下,每个.o文件都依赖于同名.c文件
第二行表示命令行输出+CC 和第一个依赖文件的名字 $<表示第一个依赖文件
第三行表示创建目标文件的所在目录 $@表示目标文件 dir $@就是目标文件所在目录
第四行是规则,表示gcc 以CFLAGS参数编译第一个依赖文件,生成目标文件
这三行前面有@,表示这三行不显示出来
最后一行则是调用自定义函数,同时传入两个参数,一个是.o文件对应的.d文件,一个是目标文件
终端会显示的内容:(也就是第四行指令对应内容)
gcc -O2 -MMD -Wall -Werror -I/home/user/ics2023/nemu/include -I/home/user/ics2023/nemu/src/engine/interpreter -I/home/use r/ics2023/nemu/src/isa/riscv32/include -O2 -D__GUEST_ISA__ =riscv32 -c -o /home/user/ics2023/nemu/build/obj-riscv32-nem u-interpreter/src/utils/timer.o src/utils/timer.c
$@ -> /home/user/ics2023/nemu/build/obj-riscv32-nemu-interpreter/src/utils/timer.o
$< -> src/utils/timer.c 剩下的都是CFLAGS
-o表示要指定生成的文件的名字 它和后面紧挨的参数是一起的
----------------------------------
init_monitor这个函数里调用别的函数而不是直接把代码展开,可以让函数看起来更简洁,此外被调用的函数在其他地方也可以进行二次利用。
此外,对于nemu/src/monitor/monitor.c这个文件,针对不同架构,通过宏决定了哪些需要进行编译。
检查发现src/isa下根本没有x86这个架构对应文件夹.
在nemu目录下make run以后,报错信息同讲义,提示monitor.c:36:welcome:assertion '0' failed。同时make指令会提示scripts/native.mk:38:run 会提示core dumped
检查montitor.c,发现这一行是assert(0) 断言这么用似乎没什么意义,所以我屏蔽了。
nemu按q退出。
cpu_exec()这个函数的参数是无符号整数,传入-1,实际上是传入int型最大值,大致相当于while(1)。
关于程序的进入和退出。在进入时,系统会将pc寄存器的值设置为当前程序的首条指令地址。退出时,系统会检测退出码,0就是向系统回报正常退出的信号。然后系统释放掉这个进程,如果有父进程的话,向父进程发一个SIGCHLD信号量,通知子进程结束的消息。
假如make run以后,直接在nemu中输入q,那么native.mk:38会提示报错。打开这个mk文件,第38行对应NEMU_EXEC这个变量,这个变量对应 $(BINARY) $(ARGS) $(IMG)
直接退出报错,可能是因为当前还在执行make指令,但是直接退出相当于指令执行失败,导致返回非0值,make报错。 我把这一行变量后面加了个 ||true,这样最终这行返回一定是零值。加上以后,确实不再报错。
----------------------------------
makefile的工作原理(个人理解):make指令运行到程序开始运行,并不代表make已经运行结束。nemu里直接退出,导致程序在退出时没有正确返回值,所以make的这一行指令也没有对应到零,进而报错。如果想要不报错,要么用 }}true,要么在这一行指令前加 - ,表示忽略错误继续执行。
标签:PA1,编译,src,make,nemu,报错,文件,讲义 From: https://www.cnblogs.com/namezhyp/p/17999830