36

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:

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.

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
Mattie
  • 2,868
  • 2
  • 25
  • 40
yburyug
  • 1,070
  • 1
  • 8
  • 13

9 Answers9

38

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. An include file <editline/history.h> does not exist on OS X.

I tested your code with that modification, and it compiled and ran without problems.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Just ran it. Really appreciate it! I'm a C noob. Thanks :) – yburyug Apr 05 '14 at 21:33
  • 1
    Undefined symbols for architecture x86_64: "_add_history", referenced from: _main in prompt-OYsOTI.o "_readline", referenced from: _main in prompt-OYsOTI.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) – Vinit Kumar Apr 06 '14 at 11:10
  • 8
    @Vinit: Did you add "libedit.dylib" to the link libraries of your project? (That's what the `-ledit` option is for in the question.) – Martin R Apr 06 '14 at 11:19
  • 1
    Nope, I didn't. I was using the same example as in the question. When I compiled it gave the following error. – Vinit Kumar Apr 06 '14 at 13:32
  • This solution works for even **Fedora 20**. I had the exact same problem as the OP on Fed20. Of course I did `gcc -ledit` and it says `undefined symbol etc` which means it found the library. If it cribs about not finding the library then the problem is something else. – gideon Jun 11 '14 at 10:45
  • 3
    @Vinit You should use `cc -std=c99 -Wall test.c -ledit -o test`, note that __ledit__. – Allen May 27 '15 at 09:19
  • I'm on OSX 10.11.1 and was getting `ld: symbol(s) not found for architecture x86_64` until I noticed @Allen's comment, which is what did the trick for me. – turboladen Dec 07 '15 at 06:34
  • add `SET(CMAKE_CXX_FLAGS "-ledit")` in CMakeLists.txt works for me at MacOS. – LoranceChen Jun 07 '18 at 06:52
8

Using OSX Yosemite. I removed #include<editline/history.h>

and then used cc -std=c99 -Wall test.c -ledit -o test

Works fine now

naivecitizen
  • 141
  • 1
  • 5
4

I'm on El Capitan, Remove #include <editline/history.h>, and use cc -std=c99 -Wall test.c -ledit -o test works for me.
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. 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
Cœur
  • 37,241
  • 25
  • 195
  • 267
Rachel
  • 237
  • 1
  • 7
3

I'm on 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

I hope this can help.

shuxiong
  • 103
  • 1
  • 7
2

I'm on OSX Mavericks and removing the line worked for me:

#include <editline/history.h>
Code Maverick
  • 20,171
  • 12
  • 62
  • 114
copio
  • 29
  • 3
1

The solution for those following along on FreeBSD (might work on other Unices as well):

#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.

cmaceachern
  • 419
  • 4
  • 10
1

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. to begin...

man editline

#include <histedit.h>

Ok, editline gives you some structs for line input and history, and functions to operate on them. First you have to instantiate these structs. The documentation for editline is not very helpful because it doesn't contain any examples. Apple makes the header file available so that helps a little. 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. Fortunately someone wiser than I has already dug into it and implemented a command line using lbedit. His code is here: 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.

/* 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. 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. To compile:

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

-ledit is needed to link editline

If it has any relevance, I am using macOs 10.4.11 and here's my compiler, output of gcc --version

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. The next step would be to add preprocessor directives so that it uses readline on linux and editline on macos.

  • thanks for this, on High Sierra the other solutions do not work. also, question... I know its probably bad practice but doesn't the OS clear up the memory when the process exits? i.e. aren't memory leaks are only a problem if they happen during continuing execution ? – James Cat Nov 13 '18 at 16:02
1

If you are on ubuntu add the editline library sudo apt-get install libtedit-dev

0

On Debian Buster 10, I had to install the package with:

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.

  • Does someone knows how to do the same process in FreeBSD? I installed the binary editline but don't know how to execute or modify the program. – Nicolás Gómez Nov 19 '20 at 15:21