Подтвердить что ты не робот

Editline/history.h и editline/readline.h не найдено/работает на OSX при попытке скомпилировать с уже установленными инструментами разработчика

Я работаю над этим уроком по созданию собственного 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.

Я установил инструменты для разработчиков osx, и brew показывает, что readline установлен, и он не знает, что делать, когда я пытаюсь brew установить editline.

Это мой код:

  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 } 

Это, очевидно, очень просто, но я действительно хочу, чтобы этот проект катился, поэтому я надеюсь, что смогу это понять. Это то, что я использую для компиляции:

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

Ответ 1

Включить только

#include <editline/readline.h>

который должен существовать, если установлены средства командной строки. Этот файл содержит "readline wrapper" для libedit, включая функции истории. В OS X отсутствует файл include <editline/history.h>.

Я проверил ваш код с этой модификацией, и он скомпилировался и работал без проблем.

Ответ 2

Использование OSX Yosemite. Я удалил #include<editline/history.h>

а затем используется cc -std=c99 -Wall test.c -ledit -o test

Прекрасно работает сейчас

Ответ 3

Я на Ubuntu 14.04.

попробуйте следующее:

sudo apt-get install libeditline-dev

и включите следующее:

#include <editline.h>

наконец, скомпилируйте следующим образом:

добавить -leditline в флаг

Надеюсь, это поможет.

Ответ 4

Я нахожусь в OSX Mavericks и удаляю для меня работу:

#include <editline/history.h>

Ответ 5

Я на EI Capitan, Удалите #include <editline/history.h>, и использование cc -std=c99 -Wall test.c -ledit -o test работает для меня.
Добавьте флаг -ledit до выхода flad, это процесс связывания, позволяет компилятору напрямую встраивать вызовы в editline в вашу программу. Или вы получите следующее сообщение об ошибке,

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

Ответ 6

Использование OSX. Я удалил #include<editline/history.h>

а затем используется cc -std=c99 -Wall test.c -ledit -o test

Использование флага -ledit связывает программу с библиотекой editline. Сейчас работает отлично.

Ответ 7

Решение для тех, кто идет дальше по FreeBSD (может работать и с другими Unices):

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

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

...

И запустите:

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

Без "-lreadline" на этапе компиляции он не связан, и вы получите ошибки относительно ссылки undefined на функцию "readline".

Ответ 8

Я начал встраивать свой собственный список и столкнулся с той же проблемой. Ни один из вышеперечисленных ответов не работал у меня. После небольшого исследования я узнал, что у macOs нет библиотеки чтения gnu, которая предоставляет функции readline. Различные версии MacOS обеспечивают эмуляцию readline с использованием библиотеки, называемой editline. начать...

man editline

#include <histedit.h>

Хорошо, editline дает вам несколько структур для ввода строк и истории, и функции для их работы. Сначала вам нужно создать эти структуры. Документация для editline не очень полезна, потому что она не содержит примеров. Apple делает доступным заголовочный файл, что помогает немного. http://www.opensource.apple.com/source/libedit/libedit-13/src/histedit.h

Я новичок в этом, и это было довольно странно для меня. существует некоторая версия исходного кода для libedit, доступная как пакет debian. К счастью, кто-то мудрее, чем я уже вникнул в него, и реализовал командную строку с использованием lbedit. Его код здесь: https://www.cs.utah.edu/~bigler/code/libedit.html. Я взял код мистера Биглера и код из "Сформировать свой собственный список" и объединил их, чтобы получить это.

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

Примечание: экземпляр используемых структур происходит вне цикл while, а также функции, освобождающие память этих структур. Из-за этого я добавил команду для выхода, иначе я думаю, что есть утечка памяти, если единственный способ выйти из цикла while - это прервать программу. Чтобы скомпилировать:

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

-ledit необходим для ссылки на editline

Если это имеет значение, я использую macOs 10.4.11 и здесь мой компилятор, вывод gcc --version

powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, Inc., сборка 4061)

Теперь единственная проблема с этим, и книга указывает на это, заключается в том, что c-код должен быть портативным, и это не так. Следующим шагом было бы добавить директивы препроцессора, чтобы он использовал readline для linux и editline для macos.