我目前正在阅读Gary W Flake的超级好书"自然的计算之美",他在书中介绍了口吃语言。我正在尝试将其安装在MacOSX 10.12.6(Sierra(上。
TL;DR:最终的解决方案是:
- 编辑
stutter/Makefile
和shell/Makefile
,并按-g wheel
或-g sys
替换-g root
的所有实例 - 运行以下命令(
sudo
是必需的(:
sudo IA64=1 CFLAGS='-std=gnu89' PREFIX=/usr/local make install
请参阅下面的原始问题,并阅读 rici 的答案以了解为什么必须这样设置CFLAGS。
如 INSTALL 文件中所述,唯一的依赖项是:gcc
、gnu make
、libreadline-dev
(用于 shell(和libsqlite3-dev
(用于可选的 sqlite 模块(。我确保它们是使用自制软件安装的,准确地说,我有:
- GCC 9.1.0(通过
gcc --version
获得( - make 3.81 (通过
make --version
获得( - Readline 8.0.1(通过
brew install readline
获得,并让 brew 输出已安装的版本( - SQLite 3.30.1(通过
brew install sqlite3
获得,并让brew输出已安装的版本(
安装失败,并显示以下跟踪:
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ make install
cd stutter && make install
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o read.o read.c
In file included from read.c:7:
In file included from ./builtins.h:5:
./memory.h:29:14: warning: inline function 'xcalloc' is not defined
[-Wundefined-inline]
inline void *xcalloc(size_t nmemb, size_t size);
^
read.c:15:18: note: used here
read_state *s = xcalloc(1, sizeof(read_state));
^
In file included from read.c:7:
In file included from ./builtins.h:5:
./memory.h:31:14: warning: inline function 'xmalloc' is not defined
[-Wundefined-inline]
inline void *xmalloc(size_t size);
^
read.c:54:23: note: used here
s->token = (char *) xmalloc(8);
^
In file included from read.c:7:
In file included from ./builtins.h:5:
./memory.h:33:14: warning: inline function 'xrealloc' is not defined
[-Wundefined-inline]
inline void *xrealloc(void *ptr, size_t size);
^
read.c:62:24: note: used here
s->token = (char *) xrealloc(s->token, s->buflen *= 2);
^
3 warnings generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o types.o types.c
In file included from types.c:10:
./memory.h:29:14: warning: inline function 'xcalloc' is not defined
[-Wundefined-inline]
inline void *xcalloc(size_t nmemb, size_t size);
^
types.c:56:23: note: used here
if(!o) o = (s_obj *) xcalloc(1, sizeof(s_obj));
^
In file included from types.c:10:
./memory.h:31:14: warning: inline function 'xmalloc' is not defined
[-Wundefined-inline]
inline void *xmalloc(size_t size);
^
types.c:151:31: note: used here
o->d.string.value = (char *) xmalloc(len + 1);
^
In file included from types.c:10:
./memory.h:33:14: warning: inline function 'xrealloc' is not defined
[-Wundefined-inline]
inline void *xrealloc(void *ptr, size_t size);
^
types.c:1013:26: note: used here
typedb = (typeinfo *) xrealloc(typedb, typedb_si...
^
In file included from types.c:12:
./builtins.h:113:12: warning: inline function 'nextparm' is not defined
[-Wundefined-inline]
inline int nextparm(s_obj **obj, s_obj **parm);
^
types.c:1378:8: note: used here
while(nextparm(&o, &iter)) {
^
4 warnings generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o memory.o memory.c
memory.c:160:18: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_protect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:166:20: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_unprotect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:474:16: warning: cast to 's_obj *' (aka 'struct s_obj *') from smaller
integer type 'int' [-Wint-to-pointer-cast]
gc_mark_obj((s_obj *) ((ptrint) (p->root) ^ 1));
^
3 warnings generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o eval.o eval.c
In file included from eval.c:8:
./builtins.h:113:12: warning: inline function 'nextparm' is not defined
[-Wundefined-inline]
inline int nextparm(s_obj **obj, s_obj **parm);
^
eval.c:130:9: note: used here
while(nextparm(&i, &parm)) {
^
In file included from eval.c:5:
In file included from ./eval.h:10:
./memory.h:138:13: warning: inline function 'gc_protlist_add' is not defined
[-Wundefined-inline]
inline void gc_protlist_add(s_obj *obj);
^
eval.c:138:4: note: used here
gc_protlist_add(o);
^
In file included from eval.c:5:
In file included from ./eval.h:10:
./memory.h:31:14: warning: inline function 'xmalloc' is not defined
[-Wundefined-inline]
inline void *xmalloc(size_t size);
^
eval.c:1087:24: note: used here
compx *cx = (compx *) xmalloc(sizeof(compx));
^
3 warnings generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o builtins.o builtins.c
In file included from builtins.c:56:
In file included from ./stutter.h:5:
./memory.h:31:14: warning: inline function 'xmalloc' is not defined
[-Wundefined-inline]
inline void *xmalloc(size_t size);
^
builtins.c:513:18: note: used here
p = (char *) xmalloc(strlen(obj->d.symbo...
^
In file included from builtins.c:56:
In file included from ./stutter.h:5:
./memory.h:33:14: warning: inline function 'xrealloc' is not defined
[-Wundefined-inline]
inline void *xrealloc(void *ptr, size_t size);
^
builtins.c:856:21: note: used here
str = (char *) xrealloc(str, stra);
^
In file included from builtins.c:56:
In file included from ./stutter.h:5:
./memory.h:29:14: warning: inline function 'xcalloc' is not defined
[-Wundefined-inline]
inline void *xcalloc(size_t nmemb, size_t size);
^
builtins.c:2025:11: note: used here
*data = xcalloc(1, 8 + 2 * sizeof(int));
^
3 warnings generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o mathbuiltins.o mathbuiltins.c
In file included from mathbuiltins.c:5:
./builtins.h:116:12: warning: inline function 'nextarg' is not defined
[-Wundefined-inline]
inline int nextarg(varctx *ctx, s_obj **obj, s_obj **parm);
^
mathbuiltins.c:14:6: note: used here
if(!nextarg(ctx, &obj, &parm))
^
1 warning generated.
cc -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o sforms.o sforms.c
In file included from sforms.c:2:
In file included from ./stutter.h:7:
./builtins.h:113:12: warning: inline function 'nextparm' is not defined
[-Wundefined-inline]
inline int nextparm(s_obj **obj, s_obj **parm);
^
sforms.c:27:6: note: used here
if(!nextparm(&prm, &parm))
^
In file included from sforms.c:2:
In file included from ./stutter.h:7:
./builtins.h:116:12: warning: inline function 'nextarg' is not defined
[-Wundefined-inline]
inline int nextarg(varctx *ctx, s_obj **obj, s_obj **parm);
^
sforms.c:166:7: note: used here
if(!nextarg(ctx, &obj, &asg)) {
^
In file included from sforms.c:2:
In file included from ./stutter.h:5:
./memory.h:29:14: warning: inline function 'xcalloc' is not defined
[-Wundefined-inline]
inline void *xcalloc(size_t nmemb, size_t size);
^
sforms.c:388:47: note: used here
method->d.clos_method.args = (method_arg *) xcalloc(argn...
^
3 warnings generated.
cc -shared -o libstutter-0.16.so read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o -L/usr/local/opt/readline/lib -lm
Undefined symbols for architecture x86_64:
"_gc_follow", referenced from:
_gc_mark_obj in memory.o
_gc_mark in memory.o
"_gc_harvest", referenced from:
_gc_sweep in memory.o
"_gc_protlist_add", referenced from:
_gc_record in memory.o
_funcexec in eval.o
"_nextarg", referenced from:
_next_t in builtins.o
_sb_set in builtins.o
_sb_setg in builtins.o
_sb_scar in builtins.o
_sb_consdump in builtins.o
_sb_cons in builtins.o
_sb_list in builtins.o
...
"_nextargtail", referenced from:
_sb_begin in builtins.o
_sb_cond in builtins.o
"_nextparm", referenced from:
_build_class_ancestry in types.o
_slots_merge in types.o
_class_calculate in types.o
_build_precedence_branch in types.o
_build_precedence in types.o
_update_generic_nexts in types.o
_find_next_method in types.o
...
"_xcalloc", referenced from:
_create_read_state in read.o
_alloc_s_obj in types.o
_alloc_ungc_obj in types.o
_create_eof in types.o
_create_t in types.o
_create_nil in types.o
_create_dict in types.o
...
"_xmalloc", referenced from:
_token_appch in read.o
_create_string_counted in types.o
_stream_printf in types.o
_weak_reference in types.o
_gc_alloc_protroot in memory.o
_varctx_create in memory.o
_stutter_init in memory.o
...
"_xrealloc", referenced from:
_token_appch in read.o
_gettypeid in types.o
_slots_merge in types.o
_gc_prot_free in memory.o
_gc_record in memory.o
_mark_miscfree in memory.o
_gc_sweep in memory.o
...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [libstutter-0.16.so] Error 1
make: *** [install] Error 2
似乎存在内存分配库未正确加载的问题,但是是的,至少可以说,我在 C 语言中不是很好读。欢迎任何帮助。请注意,文档本身说该安装仅针对Linux进行了测试,因此可能需要进行一些修改才能使其适用于Mac OSX。
谢谢!
编辑1:回应里奇的回答。首先感谢您的快速回答。我尝试了您的解决方案,如下行:
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ IA64=1 CFLAGS=gnu89 make install
cd stutter && make install
cc gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o read.o read.c
clang: error: no such file or directory: 'gnu89'
make[1]: *** [read.o] Error 1
make: *** [install] Error 2
我猜CFLAGS格式不正确,所以我尝试了以下方法,这带来了另一个错误,这让我认为我们缺少其他东西:
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ IA64=1 CFLAGS='-std=gnu89' make install
cd stutter && make install
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o read.o read.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o types.o types.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o memory.o memory.c
memory.c:160:18: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_protect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:166:20: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_unprotect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:474:16: warning: cast to 's_obj *' (aka 'struct s_obj *') from smaller
integer type 'int' [-Wint-to-pointer-cast]
gc_mark_obj((s_obj *) ((ptrint) (p->root) ^ 1));
^
3 warnings generated.
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o eval.o eval.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o builtins.o builtins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o mathbuiltins.o mathbuiltins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/share/stutter" -I/usr/local/opt/readline/include -c -o sforms.o sforms.c
cc -shared -o libstutter-0.16.so read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o -L/usr/local/opt/readline/lib -lm
rm -f libstutter.so
ln -s libstutter-0.16.so libstutter.so
rm -f libstutter.a
ar scq libstutter.a read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o
ranlib libstutter.a
install -o root -g root -m755 -d /usr/lib
install: root: Invalid argument
make[1]: *** [install] Error 67
make: *** [install] Error 2
你知道这个新错误是怎么回事吗? 不知何故,根似乎是无效的参数?
编辑 2:我从这个不相关的 github 线程中发现 OSX 上不存在root
组,所以我手动编辑了shell/Makefile
和stutter/Makefile
,以按照线程中的建议-g wheel
替换所有-g root
实例。我越来越近了,但现在面临一个新的错误:
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ IA64=1 CFLAGS='-std=gnu89' PREFIX=/usr/local make install
cd stutter && make install
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o read.o read.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o types.o types.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o memory.o memory.c
memory.c:160:18: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_protect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:166:20: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_unprotect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:474:16: warning: cast to 's_obj *' (aka 'struct s_obj *') from smaller
integer type 'int' [-Wint-to-pointer-cast]
gc_mark_obj((s_obj *) ((ptrint) (p->root) ^ 1));
^
3 warnings generated.
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o eval.o eval.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o builtins.o builtins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o mathbuiltins.o mathbuiltins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -I/usr/local/opt/readline/include -c -o sforms.o sforms.c
cc -shared -o libstutter-0.16.so read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o -L/usr/local/opt/readline/lib -lm
rm -f libstutter.so
ln -s libstutter-0.16.so libstutter.so
rm -f libstutter.a
ar scq libstutter.a read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o
ranlib libstutter.a
install -o root -g sys -m755 -d /usr/local/lib
install: chown 0:3 /usr/local/lib: Operation not permitted
install -o root -g sys -m755 -d /usr/local/include/stutter
install: chown 0:3 /usr/local/include/stutter: Operation not permitted
install -o root -g sys -m755 -d /usr/local/share/stutter
install: chown 0:3 /usr/local/share/stutter: Operation not permitted
install -o root -g sys -m755 libstutter-0.16.so libstutter.so libstutter.a /usr/local/lib
install: /usr/local/lib/libstutter-0.16.so: chown/chgrp: Operation not permitted
make[1]: *** [install] Error 71
make: *** [install] Error 2
这似乎与这个线程有关,该线程指出高山脉不允许再在/usr/local
中嘶吼。不知道如何摆脱这种情况。
编辑4:只需添加sudo
即可工作,并在顶部添加最终解决方案。
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ sudo IA64=1 CFLAGS='-std=gnu89' PREFIX=/usr/local make install
cd stutter && make install
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o read.o read.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o types.o types.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o memory.o memory.c
memory.c:160:18: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_protect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:166:20: warning: cast to 'varctx *' (aka 'struct varctx *') from
smaller integer type 'int' [-Wint-to-pointer-cast]
gc_unprotect_root((varctx *) ((ptrint)obj | 1));
^
memory.c:474:16: warning: cast to 's_obj *' (aka 'struct s_obj *') from smaller
integer type 'int' [-Wint-to-pointer-cast]
gc_mark_obj((s_obj *) ((ptrint) (p->root) ^ 1));
^
3 warnings generated.
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o eval.o eval.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o builtins.o builtins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o mathbuiltins.o mathbuiltins.c
cc -std=gnu89 -g -Wall -DVERSION="0.16" -DREFPATH="/usr/local/share/stutter" -c -o sforms.o sforms.c
cc -shared -o libstutter-0.16.so read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o -lm
rm -f libstutter.so
ln -s libstutter-0.16.so libstutter.so
rm -f libstutter.a
ar scq libstutter.a read.o types.o memory.o eval.o builtins.o mathbuiltins.o sforms.o
ranlib libstutter.a
install -o root -g sys -m755 -d /usr/local/lib
install -o root -g sys -m755 -d /usr/local/include/stutter
install -o root -g sys -m755 -d /usr/local/share/stutter
install -o root -g sys -m755 libstutter-0.16.so libstutter.so libstutter.a /usr/local/lib
install -o root -g sys -m644 lib/* /usr/local/share/stutter
install -o root -g sys -m644 types.h memory.h eval.h builtins.h stutter.h read.h /usr/local/include/stutter
cd shell && make install
cc -c -o main.o main.c -std=gnu89 -I../stutter
main.c:26:9: warning: implicitly declaring library function 'strlen' with type
'unsigned long (const char *)' [-Wimplicit-function-declaration]
len = strlen(text);
^
main.c:26:9: note: include the header <string.h> or explicitly provide a
declaration for 'strlen'
main.c:39:6: warning: implicitly declaring library function 'strncasecmp' with
type 'int (const char *, const char *, unsigned long)'
[-Wimplicit-function-declaration]
if(strncasecmp(name, text, len) == 0)
^
main.c:39:6: note: include the header <strings.h> or explicitly provide a
declaration for 'strncasecmp'
main.c:40:11: warning: implicitly declaring library function 'strdup' with type
'char *(const char *)' [-Wimplicit-function-declaration]
return strdup(name);
^
main.c:40:11: note: include the header <string.h> or explicitly provide a
declaration for 'strdup'
main.c:96:21: warning: implicitly declaring library function 'isspace' with type
'int (int)' [-Wimplicit-function-declaration]
if(*c && beg && !isspace(*c))
^
main.c:96:21: note: include the header <ctype.h> or explicitly provide a
declaration for 'isspace'
4 warnings generated.
cc -o stt main.o -lstutter -L../stutter -lm -lreadline
install -o root -g sys -m755 -d /usr/local/bin
install -o root -g sys -m755 stt /usr/local/bin
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ ls
INSTALL Makefile README doc/ shell/ stutter/ tests/
Guillaume@Guillaumes-MacBook-Pro:~/Downloads/stutter-0.16$ stt
Welcome to STUTTER 0.16
>
嗯!非常感谢里奇!
这里的问题是源代码是为旧版本的 GCC 编写的,该版本使用自己的特殊、非标准语义来inline
声明。inline
声明后来被合并到C标准中,但语义略有不同。
GCC 允许您使用-std
命令行选项指定用于编译源代码的几种可能标准之一,包括包含 GNU 扩展的选项。多年来,默认的-std
设置是gnu89
,即原始的ANSI C标准,带有(许多(GNU扩展,包括GNU的inline
提案。最新版本的 GCC 改为使用默认的gnu99
,它使用带有(较少(GNU 扩展的 C99;在此版本中,inline
带有 C 标准语义。
由于您安装的 GCC 使用 C99+gnu 作为默认值,因此 STUTTER 源代码将无法正确编译。(这不仅限于OS X;它在Linux上也表现出同样的问题。因此,您需要告诉GCC使用-std=gnu89
以重现编写源代码的标准。(你也可以修复源代码,但这将需要更多的工作。
要重新编译项目,首先需要清除已经执行的错误编译。您可以从下载的压缩包中重新创建构建文件,但似乎以下内容可以工作:
make clean
IA64=1 CFLAGS=-std=gnu89 make install
(根据INSTALL
,IA64=1
表示您正在构建64位系统,我想您是。
最终的解决方案是:
-
编辑
stutter/Makefile
和shell/Makefile
,并按-g wheel
或-g sys
替换-g root
的所有实例,因为OSX中默认情况下不存在root
组。 -
运行以下命令(
sudo
是必需的(。CFLAGS
有必要指出gcc
-std
论证的旧标准,详见 rici 的回答
sudo IA64=1 CFLAGS='-std=gnu89' PREFIX=/usr/local make install