私はあなた自身の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 installeditlineを試してみるとどうしたらよいかわかりません。
これは私のコードです:
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
含めるのみ
#include <editline/readline.h>
これは、コマンドラインツールがインストールされている場合に存在するはずです。このファイルには、履歴関数を含むlibeditの「readlineラッパー」が含まれています。インクルードファイル<editline/history.h>
はOSXには存在しません。
その変更を加えてコードをテストしたところ、問題なくコンパイルされて実行されました。
OSXYosemiteを使用します。 #include<editline/history.h>
を削除しました
その後、cc -std=c99 -Wall test.c -ledit -o test
を使用しました
今は正常に動作します
私はUbuntu14.04を使用しています。
これを試して:
Sudo apt-get install libeditline-dev
次のように含めます。
#include <editline.h>
最後に次のようにコンパイルします。
追加 -leditline
旗の中
これがお役に立てば幸いです。
私はOSXMavericksを使用していて、行を削除するとうまくいきました。
#include <editline/history.h>
私は独自のリストを作成するから始めて、同じ問題に遭遇しました。上記の答えはどれも私にはうまくいきませんでした。少し調べてみたところ、macOにはreadline関数を提供するgnu readlineライブラリがないことがわかりました。異なるバージョンのMacOは、editlineと呼ばれるライブラリを使用してreadlineのエミュレーションを提供します。始める...
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 。 Bigler氏のコードと、独自のリストを作成するのコードを取得し、それらを組み合わせてこれを取得しました。
/* 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
-editlineをリンクするにはleditが必要です
関連性がある場合は、macOs 10.4.11を使用しています。これが私のコンパイラで、gcc --version
の出力です。
powerpc-Apple-darwin8-gcc-4.0.0(GCC)4.0.0 20041026(Apple Computer、Inc。ビルド4061)
現在、これに関する唯一の問題は、本がこれを指摘していることですが、cコードは移植可能であると想定されており、そうではありません。次のステップは、プリプロセッサディレクティブを追加して、Linuxではreadlineを使用し、macosではeditlineを使用するようにすることです。
私はエルキャピタンにいます。#include <editline/history.h>
を削除し、cc -std=c99 -Wall test.c -ledit -o test
を使用してください。
出力フラッドの前にフラグ-ledit
を追加します。これはリンクプロセスであり、コンパイラがエディットラインへの呼び出しをプログラムに直接埋め込むことができるようにします。または、次のエラーメッセージが表示されます。
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
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」がないと、リンクされておらず、「readline」関数への未定義の参照に関するエラーが発生します。