简体   繁体   English

尝试使用已安装的开发人员工具进行编译时,在 macOS 上找不到 editline/history.h 和 editline/readline.h/正在工作

[英]editline/history.h and editline/readline.h not found/working on macOS when trying to compile with developer tools installed already

I am working on this tutorial on building your own LISP ( http://www.buildyourownlisp.com/chapter4_interactive_prompt ) and for some reason when I try to compile I get this:我正在编写有关构建自己的 LISP( http://www.buildyourownlisp.com/chapter4_interactive_prompt )的教程,由于某种原因,当我尝试编译时,我得到了这个:

REPL.c:4:10: fatal error: 'editline/readline.h' file not found
#include <editline/history.h>
^
1 error generated.

I have installed the macOS developer tools, and brew is showing readline is installed and it doesn't know what to do when I try brew install editline.我已经安装了 macOS 开发人员工具,并且 brew 显示已安装 readline,当我尝试 brew install editline 时它​​不知道该怎么做。

This is my code:这是我的代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <editline/readline.h>
  4 #include <editline/history.h>
  5 
  6 int main(int argc, char** argv) {
  7      
  8   /* version/exit info */
  9   puts("Edward Version 0.0.1");
 10   puts("Press Ctrl+c to Exit\n");
 11          
 12   /* endless loop for main REPL */
 13   while (1) { 
 14     /* output prompt and read line */
 15     char* input = readline("lispy> ");
 16                   
 17     /* put input in history  */
 18     add_history(input);
 19                       
 20     /* Echo input back */                          
 21     printf("No you're a %s\n", input);
 22                       
 23     /* free input */
 24     free(input);
 25   }                           
 26   return 0;
 27 } 

It is obviously very basic, but I really want to get this project rolling so I'm hoping I can figure this out.这显然是非常基本的,但我真的很想让这个项目滚动,所以我希望我能解决这个问题。 This is what I'm using to compile:这是我用来编译的:

cc -std=c99 -Wall REPL.c -ledit -o REPL

Include only仅包括

#include <editline/readline.h>

which should exist if the command line tools are installed.如果安装了命令行工具,它应该存在。 This file contains the "readline wrapper" for libedit, including the history functions as well.该文件包含 libedit 的“readline wrapper”,还包括历史函数。 An include file <editline/history.h> does not exist on OS X. OS X 上不存在包含文件<editline/history.h>

I tested your code with that modification, and it compiled and ran without problems.我用那个修改测试了你的代码,它编译并运行没有问题。

Using OSX Yosemite.使用 OSX 优胜美地。 I removed #include<editline/history.h>我删除了#include<editline/history.h>

and then used cc -std=c99 -Wall test.c -ledit -o test然后使用cc -std=c99 -Wall test.c -ledit -o test

Works fine now现在工作正常

I'm on El Capitan, Remove #include <editline/history.h> , and use cc -std=c99 -Wall test.c -ledit -o test works for me.我在 El Capitan,删除#include <editline/history.h> ,并使用cc -std=c99 -Wall test.c -ledit -o test对我有用。
Add the flag -ledit before the output flad, it's a linking process, allows the compiler to directly embed calls to editline in your program.在输出flad之前添加标志-ledit ,这是一个链接过程,允许编译器直接在你的程序中嵌入对editline的调用。 Or, you'll get the below error message,或者,您将收到以下错误消息,

Undefined symbols for architecture x86_64:
  "_add_history", referenced from:
      _main in prompt-086f90.o
  "_readline", referenced from:
      _main in prompt-086f90.o
ld: symbol(s) not found for architecture x86_64

I'm on Ubuntu 14.04.我在 Ubuntu 14.04 上。

try this:尝试这个:

sudo apt-get install libeditline-dev

and include like this:并包括这样的:

#include <editline.h>

finally compile like this:最后编译如下:

add -leditline in the flag在标志中添加-leditline

I hope this can help.我希望这会有所帮助。

我在 OSX Mavericks 并删除了对我有用的行:

#include <editline/history.h>

The solution for those following along on FreeBSD (might work on other Unices as well):那些关注 FreeBSD 的人的解决方案(可能也适用于其他 Unices):

#include <stdio.h>
#include <stdlib.h>

#include <readline/readline.h>
#include <readline/history.h>

...

And run:并运行:

$ cc test.c -Wall -std=c99 -lreadline -o test

Without "-lreadline" in the compile step it is not linked in and you will get errors about undefined reference to "readline" function.如果在编译步骤中没有“-lreadline”,则不会链接,您将收到有关未定义引用“readline”函数的错误。

I started in on Build your own list and ran into the same problem.我从建立你自己的列表开始,遇到了同样的问题。 None of the above answers worked for me.以上答案都不适合我。 After a little research I found out that macOs doesn't have the gnu readline library that provides the readline functions, Different versions of MacOs provide emulation of readline using a library called editline.经过一番研究,我发现 macOS 没有提供 readline 功能的 gnu readline 库,不同版本的 MacOs 使用名为 editline 的库提供了 readline 的模拟。 to begin...开始...

man editline

#include <histedit.h>

Ok, editline gives you some structs for line input and history, and functions to operate on them.好的,editline 为您提供了一些用于行输入和历史记录的结构,以及对它们进行操作的函数。 First you have to instantiate these structs.首先,您必须实例化这些结构。 The documentation for editline is not very helpful because it doesn't contain any examples. editline 的文档不是很有帮助,因为它不包含任何示例。 Apple makes the header file available so that helps a little. Apple 提供了头​​文件,因此有点帮助。 http://www.opensource.apple.com/source/libedit/libedit-13/src/histedit.h http://www.opensource.apple.com/source/libedit/libedit-13/src/histedit.h

I am new to this and it was still pretty confusing to me.我对此很陌生,对我来说仍然很困惑。 there is some version of the source code to libedit available as a debian package.有一些版本的 libedit 源代码作为 debian 包提供。 Fortunately someone wiser than I has already dug into it and implemented a command line using lbedit.幸运的是,比我更聪明的人已经深入研究并使用 lbedit 实现了一个命令行。 His code is here: https://www.cs.utah.edu/~bigler/code/libedit.html .他的代码在这里: https ://www.cs.utah.edu/~bigler/code/libedit.html。 I took Mr Bigler's code, and the code from Build your own list , and put them together to get this.我把 Bigler 先生的代码和Build your own list 中的代码放在一起得到了这个。

/* repl-macos.c
 * Repl code example from builyourownlisp.com
 * Modified by NB aug 2017
 * Code example for editline from
 * www.cs.utah.edu/~bigler/code/libedit.html
 */

#include <stdio.h>
#include <string.h>
#include <histedit.h>

char* prompt(EditLine *e){
return "lispy> ";
}

int main(int argc, char** argv){

    EditLine *el; // Line editor state
    History *herstory; // the rest is history

    // Temp Variables   
    int count;
    const char *usrin;
    int keepreading = 1;
    HistEvent ev;

    // Initialize the editline state
    el = el_init(argv[0], stdin, stdout, stderr);
    el_set(el, EL_PROMPT, &prompt);
    el_set(el, EL_EDITOR, "emacs");

    // Initialize history
    herstory = history_init();
    if(!herstory){
        fprintf(stderr, "Couldn't initialize history\n");
        return 1;
    }

    //set history size
    history(herstory, &ev, H_SETSIZE, 800);
    // Set up the call back functions for history functionality
    el_set(el, EL_HIST, history, herstory);

    puts("Begin moLisp interpreter");
    puts("Type 'exit' at prompt to exit");

    while(keepreading){
        usrin = el_gets(el, &count);

    // add the command to the history, and echo it back to the user
        if(count > 0){
            history(herstory, &ev, H_ENTER, usrin);
            if(strcmp(usrin, "exit\n"))
                printf("No, You're a %s", usrin);
            else{
                puts("bye");
                --keepreading;
            }
        }   
    }

  // Clean up memory 
  // by freeing the memory pointed to within the structs that
  // libedit has created.
  history_end(herstory);
  el_end(el);


  return 0;
}

Notice: The instantiation of the structs that are used happens outside of the while loop, and so do the functions that free the memory those structs are using.注意:使用的结构的实例化发生在 while 循环之外,释放这些结构正在使用的内存的函数也是如此。 Because of this, I added the command to exit, otherwise I think there's a memory leak if the only way to exit the while loop is by interrupting the program.因此,我添加了退出命令,否则我认为如果退出 while 循环的唯一方法是中断程序,则会出现内存泄漏。 To compile:编译:

gcc repl-macos.c -ledit -Wall -o repl-edit

-ledit is needed to link editline -ledit 需要链接编辑线

If it has any relevance, I am using macOs 10.4.11 and here's my compiler, output of gcc --version如果它有任何相关性,我使用的是 macOS 10.4.11,这是我的编译器, gcc --version的输出

powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, Inc. build 4061) powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, Inc. build 4061)

Now the only problem with this, and the book points this out, is that c-code is supposed to be portable and this isn't.现在唯一的问题,这本书指出了这一点,是 c 代码应该是可移植的,而这不是。 The next step would be to add preprocessor directives so that it uses readline on linux and editline on macos.下一步是添加预处理器指令,以便它在 linux 上使用 readline,在 macos 上使用 editline。

如果您使用的是 ubuntu,请添加编辑线库sudo apt-get install libtedit-dev

On Debian Buster 10, I had to install the package with:在 Debian Buster 10 上,我必须使用以下命令安装软件包:

sudo apt install libeditline-dev 

Instead of:代替:

#include <editline/readline.h>
#include <editline/history.h>

I just included:我刚刚包括:

#include <editline.h>

ran the program with -leditline flag and worked perfectly.使用 -leditline 标志运行程序并完美运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM