C 可加载Bash内置
我正在写一个strcmp bash内置。它编译得很好,但当我尝试启用它时,我得到:C 可加载Bash内置,c,bash,strcmp,built-in,C,Bash,Strcmp,Built In,我正在写一个strcmp bash内置。它编译得很好,但当我尝试启用它时,我得到: $ enable -f ./strcmp strcmp bash: enable: cannot open shared object ./strcmp: ./strcmp: only ET_DYN and ET_EXEC can be loaded 我的车的主要部分是: strcmp_builtin (list) WORD_LIST *list; char *strcmp_doc[] = { (ch
$ enable -f ./strcmp strcmp
bash: enable: cannot open shared object ./strcmp: ./strcmp: only ET_DYN and ET_EXEC can be loaded
我的车的主要部分是:
strcmp_builtin (list)
WORD_LIST *list;
char *strcmp_doc[] = {
(char *)NULL
};
struct builtin strcmp_struct = {
"strcmp", /* builtin name */
strcmp_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
strcmp_doc, /* array of long documentation strings. */
"strcmp 'string 1' 'string 2'", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
编译行(来自扩展的make文件):
我在谷歌上搜索了ET_DYN和ET_EXEC,只找到了类似问题的链接 我不确定,但是。。。是否尝试过
gcc-shared
?您是否注意到-c
标志?这使它无法链接。将其替换为-shared
,正如@shr所提到的对我的具体问题(ET_-DYN和ET_-EXEC)的一点后续回答,以及对@stanparker的答案正确原因的扩展
ET_DYN和ET_EXEC是ELF可执行类型。在ELF头中,有一个字段Elf32\u-Half e\u-type
或Elf64\u-Half e\u-type
,其中可能包含多个ET*enum。我猜ET是“可执行类型”,EXEC可执行和DYN动态。这应该足以表明发出的工件实际上不是任何类型的可执行对象,并且应该鼓励更仔细地查看GCC标志。(有关ELF标头的详细信息,请参阅)
现在我们看到我们没有链接,让我们删除-c标志。然后,我们将得到第二个错误(这次是在编译的某个地方)
这里实际上有两个错误。第一个是“对'main'的未定义引用”,第二个是“对'make_builtin_argv'(bash内部函数)的未定义引用”。最后一行足以说明GCC在链接过程中正在消亡。函数_start是glibc定义的公共入口点,glibc本身实际上在程序中调用main。在这一点上,duh,我们不是在制作一个可执行文件,而是一个共享库。将-shared
添加到命令行可以让我们完美地进行编译
那么,为什么make不给我一个“正确”的命令行呢?Makefile.in不会动态测试源文件,所以我应该手动添加.c和.o目标,然后重新运行。/configure。这样做之后,我们得到了
$ make strcmp
gcc [...] -c -o strcmp.o strcmp.c
gcc -shared -Wl,-soname,strcmp -L./lib/termcap -o strcmp strcmp.o
它有用吗
$ enable -f ./strcmp strcmp
$ strcmp "hi" "ho"
$ echo $?
2
$ strcmp "hi" "ha"
$ echo $?
1
$ strcmp "hi" "hi"
$ echo $?
0
这就是我期望它能做的,所以它看起来确实有效
无论如何,我写这篇文章的目的是,这不是我个人第一次在GCC和C编译方面陷入混乱。这不是我第一次看到有人总的来说有这些问题。要获得成功的C编译,需要做大量的工作,每个阶段都很重要。所以,我写这篇文章是为了提醒自己GCC(cc、ld和elf LIB)到底在做什么,为什么这里和那里的一个小角色很重要,以及整个发现过程。我还没有在其他地方看到它被打印出来,所以这里是我所拥有的
另外,对于那些对这个内置程序感兴趣的人来说,它将出现在我的网站上,愚蠢的我,甚至连看都不看就相信make文件。是的,不喜欢。谢谢
$ make strcmp
gcc [...] -c -o strcmp.o strcmp.c
gcc -shared -Wl,-soname,strcmp -L./lib/termcap -o strcmp strcmp.o
$ enable -f ./strcmp strcmp
$ strcmp "hi" "ho"
$ echo $?
2
$ strcmp "hi" "ha"
$ echo $?
1
$ strcmp "hi" "hi"
$ echo $?
0