我有一个家庭作业,要求我们使用系统调用而不是标准库来打开,读取和写入文件。为了调试它,我想在测试编译项目时使用std库。我这样做了:
#ifdef HOME
//Home debug prinf function
#include <stdio.h>
#else
//Dummy prinf function
int printf(const char* ff, ...) {
return 0;
}
#endif
我按照这样编译:{{1}}
问题是我使用gcc -DHOME -m32 -static -O2 -o main.exe main.c
参数,标准入口点是-nostdlib
但没有参数,入口点是void _start
。你可能会这样做:
int main(const char** args)
在这种情况下,这是您在没有//Normal entry point
int main(const char** args) {
_start();
}
//-nostdlib entry point
void _start() {
//actual code
}
编译时获得的结果:
-nostdlib
因此,我需要检测是否包含stdlib,并且在这种情况下不要定义/tmp/ccZmQ4cB.o: In function `_start':
main.c:(.text+0x20): multiple definition of `_start'
/usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o:(.text+0x0): first defined here
。
答案 0 :(得分:2)
系统的低级入口点始终为_start
。对于-nostdlib
,其定义从链接中省略,因此您必须提供一个。如果没有-nostdlib
,则不得尝试定义它;即使这没有从重复定义中获得链接错误,它也会严重破坏标准库运行时的启动。
相反,请尝试反过来:
int main() {
/* your code here */
}
#ifdef NOSTDLIB_BUILD /* you need to define this with -D */
void _start() {
main();
}
#endif
您可以选择将假参数添加到main
。但是用C语言编写的_start
不可能得到真实的。你需要在asm中写_start
。
请注意,-nostdlib
是链接器选项,而不是编译时,因此无法在编译时自动确定{{1}将被使用。而只需创建自己的宏并将其作为-nostdlib
或类似的命令行传递给它。