我有一个C源文件,带主要功能和其他一些功能。像这样:
#include "stdlib.h"
int program(int argc, char ** argv)
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
return a + b;
}
int main(int argc, char ** argv)
{
return program(argc, argv);
}
我知道如何将其编译为二进制文件。
是否可以将其编译为省略了main
符号/功能的目标文件?
我知道我可以通过将main
拆分到自己的文件中来实现自己的目标,但是我不想这样做。
答案 0 :(得分:3)
通常,在库中定义main()
并不是问题,因为链接器仅在任何非库二进制文件中没有main()
的情况下才使用它。甚至可以利用它来包含默认的main()
。例如,请参见与-ll
一起使用的Posix标准lex
库(如果使用flex则为-lfl
)。
如果确实要确保该符号不可用于解析,则可以从库中删除该符号。有一些用于处理二进制文件的工具,这些工具因系统而异。例如,看一下objcopy的--strip-symbol
选项。 (这不会删除已编译的代码;只会使其无法解析。)
答案 1 :(得分:1)
库只是对象模块的存档-要省略main()
,它必须位于单独的对象模块中,然后从库构建中省略它,或者使用条件编译,以便在以下位置将其省略编译时间。
实际上,如果main
位于单独的对象模块中,则不忽略它并不重要,因为直接链接的对象模块中的任何定义都将覆盖任何静态库定义,因此仅使用库定义如果未重新定义。我不确定如果main()
是在包含二进制中引用的其他符号的模块中定义的,是否行得通,但是如果您尝试除重复符号错误以外的操作,则不会发生任何不良情况。
答案 2 :(得分:1)
有没有一种方法可以将其编译为目标文件 符号/功能省略了吗?
因此,您不希望符号main出现在目标文件中。 这可能是一种方法。
file.c
<script>
const data=[
{IsOpen: true, Day: "Monday", Desc: "09:00 AM-5:00 PM"},
{IsOpen: true, Day: "Sunday", Desc: "09:00 AM-11:30 PM"},
{IsOpen: true, Day: "Wednesday", Desc: "09:00 AM-5:00 PM"},
{IsOpen: true, Day: "Friday", Desc: "09:00 AM-5:00 PM"},
{IsOpen: true, Day: "Tuesday", Desc: "09:00 AM-5:00 PM"},
{IsOpen: true, Day: "Thursday", Desc: "09:00 AM-5:00 PM"},
{IsOpen: true, Day: "Saturday", Desc: "09:00 AM-5:00 PM"},
]
</script>
然后编译 [gcc]
gcc file.c -o文件-e not_main -nostartfiles
符号表:
#include "stdlib.h"
int program(int argc, char ** argv)
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
return a + b;
}
int not_main(int argc, char ** argv)
{
exit(0);
}
答案 3 :(得分:0)
有没有一种方法可以将其编译成目标文件,而省略主要符号/功能?
是的,通过使用preprocessor技巧和/或preprocessor options编译器。
将您的C代码(在文件mycode.c
中)更改为包含以下内容:
#ifdef HAVE_MAIN
int main(int argc, char ** argv)
{
return program(argc, argv);
}
#endif
然后,仅获取目标文件mycode.o
,编译为gcc -Wall -Wextra -g mycode.c -c -o mycode.o
(如果使用GCC)
要获取整个程序myprog
,请将其编译为gcc -Wall -Wextra -g -DHAVE_MAIN mycode.c -o myprog
您甚至可以(避免使用任何#ifdef HAVE_MAIN
的情况下,使用gcc -Wall -Wextra -g -Dmain=mymain -c mycode.c
进行编译,以通过预处理将main
重命名为mymain
(然后失去了魔幻的作用)进入点的状态)。
但是,这样做被认为是不好的味道(不是很可读的代码)。您最好将main
放在另一个translation unit中,并仅在需要整个程序时才对其进行编译。通常,library(或executable)是由几个翻译单元(每个翻译单元编译成一些object file;目标文件集会得到{ {3}})。您实际上将使用某些linked工具(例如build automation或make等)来构建它。