检测-nostdlib或仅检测stdlib是否可用

时间:2015-04-07 15:31:02

标签: c gcc

我有一个家庭作业,要求我们使用系统调用而不是标准库来打开,读取和写入文件。为了调试它,我想在测试编译项目时使用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

1 个答案:

答案 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或类似的命令行传递给它。