c macos readline editline

editline/history.h y editline/readline.h no encontrado/trabajando en OSX al intentar compilar con herramientas de desarrollador ya instaladas



macos (7)

Estoy trabajando en este tutorial para crear tu propio LISP ( http://www.buildyourownlisp.com/chapter4_interactive_prompt ) y por alguna razón, cuando intento compilar, obtengo esto:

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

He instalado las herramientas para desarrolladores de osx y brew está mostrando que readline está instalado y no sabe qué hacer cuando intento brew install editline.

Este es mi código:

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 }

Obviamente, es muy básico, pero realmente quiero poner en marcha este proyecto, así que espero poder resolverlo. Esto es lo que estoy usando para compilar:

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


Comencé en Construye tu propia lista y encontré el mismo problema. Ninguna de las respuestas anteriores funcionó para mí. Después de una pequeña investigación, descubrí que los macOs no tienen la biblioteca gnu readline que proporciona las funciones de readline. Las diferentes versiones de MacOs proporcionan una emulación de readline utilizando una biblioteca llamada editline. empezar...

man editline

#include <histedit.h>

Ok, editline le da algunas estructuras para la entrada de línea y el historial, y funciones para operar en ellas. Primero tienes que instanciar estas estructuras. La documentación para editline no es muy útil porque no contiene ningún ejemplo. Apple pone a disposición el archivo de cabecera, así que ayuda un poco. http://www.opensource.apple.com/source/libedit/libedit-13/src/histedit.h

Soy nuevo en esto y todavía era bastante confuso para mí. Existe una versión del código fuente de libedit disponible como paquete debian. Afortunadamente, alguien más sabio que yo ya ha investigado e implementado una línea de comandos usando lbedit. Su código está aquí: https://www.cs.utah.edu/~bigler/code/libedit.html . Tomé el código del Sr. Bigler y el código de Construye tu propia lista , y los puse juntos para obtener esto.

/* 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; }

Aviso: la creación de instancias de las estructuras que se utilizan ocurre fuera del bucle while, y también lo hacen las funciones que liberan la memoria que están utilizando esas estructuras. Debido a esto, agregué el comando para salir, de lo contrario creo que hay una pérdida de memoria si la única forma de salir del bucle while es interrumpir el programa. Compilar:

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

-ledit es necesario para enlazar editline

Si tiene alguna relevancia, estoy usando macOs 10.4.11 y aquí está mi compilador, salida de gcc --version

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

Ahora, el único problema con esto, y el libro lo señala, es que se supone que el código c es portátil y esto no lo es. El siguiente paso sería agregar directivas de preprocesador para que use readline en linux y editline en macos.


Estoy en EI Capitan, Eliminar #include <editline/history.h> , y usar cc -std=c99 -Wall test.c -ledit -o test funciona para mí.
Agregue la -ledit antes de la salida, es un proceso de vinculación, permite al compilador incrustar directamente las llamadas a editline en su programa. O, obtendrá el siguiente mensaje de error,

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


Estoy en OSX Mavericks y eliminando la línea que funcionó para mí:

#include <editline/history.h>


Estoy en Ubuntu 14.04.

prueba esto:

sudo apt-get install libeditline-dev

e incluir así:

#include <editline.h>

finalmente compilar de esta manera:

añadir -leditline en la bandera

Espero que esto pueda ayudar.


Incluir solo

#include <editline/readline.h>

que debería existir si las herramientas de línea de comandos están instaladas. Este archivo contiene el "readline wrapper" para libedit, incluidas las funciones de historial también. Un archivo de inclusión <editline/history.h> no existe en OS X.

Probé su código con esa modificación, y compilé y ejecuté sin problemas.


La solución para los que siguen en FreeBSD (también podría funcionar en otros Unices):

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

Y correr:

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

Sin "-lreadline" en el paso de compilación, no está enlazado y obtendrá errores sobre la referencia indefinida a la función "readline".


Utilizando OSX Yosemite. He eliminado #include<editline/history.h>

y luego se usó cc -std=c99 -Wall test.c -ledit -o test

Funciona bien ahora