Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 可加载Bash内置_C_Bash_Strcmp_Built In - Fatal编程技术网

C 可加载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

我正在写一个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[] = {
    (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