C编译错误 - 艰难地学习C(Ex 32)

eb8*_*b80 4 c

我在练习32的学习C艰难的方法编译时遇到了很糟糕的时间.

我已经从创建者的GitHub仓库中逐字复制了代码,甚至克隆在一个新的存储库中.我已经浏览过其他存储库,除了Ubuntu之外还尝试了我的MacOSX等等.我似乎没有做任何事情就可以编译.

我使用的是Ubuntu 12.04(见下文).

这是我的文件结构(注意 - 这是我直接从练习32中包含文件时的文件结构.显然,当我克隆git存储库时,我得到更多文件.我使用diff来确保我的所有文件,包括我的make文件,在我的削减版本中完全类似于git存储库):

$ pwd
/usr/local/me/code/C/liblcthw


$ ls
bin  LICENSE  Makefile  README.md  src  tests

$ ls tests/
list_tests.c  minunit.h  runtests.sh

$ ls src/lcthw/
dbg.h  list.c  list.h
Run Code Online (Sandbox Code Playgroud)

这是我的make命令.

$ make
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list.o src/lcthw/list.c
ar rcs build/liblcthw.a src/lcthw/list.o
ranlib build/liblcthw.a
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  build/liblcthw.a    tests/list_tests.c   -o tests/list_tests
tests/list_tests.c: In function ‘main’:
tests/list_tests.c:111:1: warning: parameter ‘argc’ set but not used [-Wunused-but-set-parameter]
/tmp/ccXlNfMl.o: In function `test_create':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:13: undefined reference to `List_create'
/tmp/ccXlNfMl.o: In function `test_destroy':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:22: undefined reference to `List_clear_destroy'
/tmp/ccXlNfMl.o: In function `test_push_pop':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:31: undefined reference to `List_push'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:34: undefined reference to `List_push'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:37: undefined reference to `List_push'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:41: undefined reference to `List_pop'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:44: undefined reference to `List_pop'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:47: undefined reference to `List_pop'
/tmp/ccXlNfMl.o: In function `test_shift':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:56: undefined reference to `List_shift'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:59: undefined reference to `List_shift'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:62: undefined reference to `List_shift'
/tmp/ccXlNfMl.o: In function `test_remove':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:74: undefined reference to `List_remove'
/tmp/ccXlNfMl.o: In function `test_unshift':
/usr/local/me/code/C/liblcthw/tests/list_tests.c:86: undefined reference to `List_unshift'
/usr/local/me/code/C/liblcthw/tests/list_tests.c:89: undefined reference to `List_unshift'
collect2: ld returned 1 exit status
make: *** [tests/list_tests] Error 1
Run Code Online (Sandbox Code Playgroud)

我使用的是Ubuntu 12.04

$ lsb_release -a
LSB Version:    core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:core-3.0-noarch:core-3.1-amd64:core-3.1-noarch:core-3.2-amd64:core-3.2-noarch:core-4.0-amd64:core-4.0-noarch:cxx-3.0-amd64:cxx-3.0-noarch:cxx-3.1-amd64:cxx-3.1-noarch:cxx-3.2-amd64:cxx-3.2-noarch:cxx-4.0-amd64:cxx-4.0-noarch:desktop-3.1-amd64:desktop-3.1-noarch:desktop-3.2-amd64:desktop-3.2-noarch:desktop-4.0-amd64:desktop-4.0-noarch:graphics-2.0-amd64:graphics-2.0-noarch:graphics-3.0-amd64:graphics-3.0-noarch:graphics-3.1-amd64:graphics-3.1-noarch:graphics-3.2-amd64:graphics-3.2-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-3.2-amd64:printing-3.2-noarch:printing-4.0-amd64:printing-4.0-noarch:qt4-3.1-amd64:qt4-3.1-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.2 LTS
Release:        12.04
Codename:       precise
Run Code Online (Sandbox Code Playgroud)

Mah*_*mer 9

从github repo下载的练习32代码是特定于BSD系统(可能是OS X)的平台.具体来说,BSD系统上存在一些成功构建的必需符号,但很可能不存在于(Linux)Ubuntu 12.04系统上.这些包括:

mergesort
heapsort
Run Code Online (Sandbox Code Playgroud)

尽管如此,库和单元测试都可以成功编译,但一个单元测试除外(最终)将需要上述符号.tests如果对下面显示的makefile中的缺陷稍有改动,那么从目录中移动单个有问题的测试将允许其他测试在(Linux)SuSE SLES 11系统上进行编译.

下载问题中提到的来源后:

.../liblcthw-master> ll
total 28
drwxr-xr-x 2 mahonri users 4096 May 24 21:30 bin
drwxr-xr-x 2 mahonri users 4096 May 24 21:53 build
-rw-r--r-- 1 mahonri users 1548 May  8  2012 LICENSE
-rw-r--r-- 1 mahonri users 1139 May  8  2012 Makefile
-rw-r--r-- 1 mahonri users 1069 May  8  2012 README.md
drwxr-xr-x 3 mahonri users 4096 May 24 21:52 src
drwxr-xr-x 2 mahonri users 4096 May 24 21:53 tests
Run Code Online (Sandbox Code Playgroud)

可以找到缺陷Makefile.这是Makefile下载的有缺陷的部分:

# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
       sh ./tests/runtests.sh
Run Code Online (Sandbox Code Playgroud)

一个问题是将$(TARGET)的值放在build/liblcthw.aCFLAGS的末尾不起作用.这是因为CFLAGS针对的是编译器,而不是链接器.因此,生成的"测试"目标不与库链接.

另一个问题是至少有一个'测试'应用程序需要一个数学库.

要解决这些问题,Makefile必须将其修改为类似于以下内容:

# The Unit Tests
.PHONY: tests
tests: LDLIBS += -lm -L./build -llcthw
tests: $(TESTS)
       sh ./tests/runtests.sh
Run Code Online (Sandbox Code Playgroud)

要构建liblcthw.a和构建"测试"应用程序,请运行此目录make中的更新Makefile:

.../liblcthw-master> ll
total 28
drwxr-xr-x 2 mahonri users 4096 May 24 21:30 bin
drwxr-xr-x 2 mahonri users 4096 May 24 21:53 build
-rw-r--r-- 1 mahonri users 1548 May  8  2012 LICENSE
-rw-r--r-- 1 mahonri users 1139 May  8  2012 Makefile
-rw-r--r-- 1 mahonri users 1069 May  8  2012 README.md
drwxr-xr-x 3 mahonri users 4096 May 24 21:52 src
drwxr-xr-x 2 mahonri users 4096 May 24 21:53 tests
.../liblcthw-master> make
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/bstree.o src/lcthw/bstree.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/bstrlib.o src/lcthw/bstrlib.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/darray_algos.o src/lcthw/darray_algos.c
src/lcthw/darray_algos.c: In function ‘DArray_heapsort’:
src/lcthw/darray_algos.c:12: warning: implicit declaration of function ‘heapsort’
src/lcthw/darray_algos.c: In function ‘DArray_mergesort’:
src/lcthw/darray_algos.c:17: warning: implicit declaration of function ‘mergesort’
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/darray.o src/lcthw/darray.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/hashmap_algos.o src/lcthw/hashmap_algos.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/hashmap.o src/lcthw/hashmap.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list_algos.o src/lcthw/list_algos.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list.o src/lcthw/list.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/radixmap.o src/lcthw/radixmap.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/ringbuffer.o src/lcthw/ringbuffer.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/sarray.o  src/lcthw/sarray.c
src/lcthw/sarray.c: In function ‘SuffixArray_create’:
src/lcthw/sarray.c:71: warning: implicit declaration of function ‘qsort_r’
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/stats.o src/lcthw/stats.c
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/tstree.o src/lcthw/tstree.c
ar rcs build/liblcthw.a src/lcthw/bstree.o src/lcthw/bstrlib.o src/lcthw/darray_algos.o src/lcthw/darray.o src/lcthw/hashmap_algos.o src/lcthw/hashmap.o src/lcthw/list_algos.o src/lcthw/list.o src/lcthw/radixmap.o src/lcthw/ringbuffer.o src/lcthw/sarray.o src/lcthw/stats.o src/lcthw/tstree.o
ranlib build/liblcthw.a
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG     tests/bstree_tests.c  -L./build -llcthw -o tests/bstree_tests
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG     tests/bstr_tests.c  -L./build -llcthw -o tests/bstr_tests
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG     tests/darray_algos_tests.c  -L./build -llcthw -o tests/darray_algos_tests
...
Run Code Online (Sandbox Code Playgroud)

然后,makefile继续运行测试可执行文件:

sh ./tests/runtests.sh
Running unit tests:
----
RUNNING: ./tests/bstree_tests
ALL TESTS PASSED
Tests run: 5
tests/bstree_tests PASS
tests/bstr_tests PASS
----
RUNNING: ./tests/darray_tests
ALL TESTS PASSED
Tests run: 8
tests/darray_tests PASS
----
RUNNING: ./tests/hashmap_algos_tests
ALL TESTS PASSED
Tests run: 4
tests/hashmap_algos_tests PASS
----
RUNNING: ./tests/hashmap_tests
ALL TESTS PASSED
Tests run: 5
tests/hashmap_tests PASS
----
RUNNING: ./tests/list_algos_tests
ALL TESTS PASSED
Tests run: 2
tests/list_algos_tests PASS
----
RUNNING: ./tests/list_tests
ALL TESTS PASSED
Tests run: 6
tests/list_tests PASS
----
RUNNING: ./tests/queue_tests
ALL TESTS PASSED
Tests run: 3
tests/queue_tests PASS
----
RUNNING: ./tests/radixmap_tests
ALL TESTS PASSED
Tests run: 1
tests/radixmap_tests PASS
----
RUNNING: ./tests/ringbuffer_tests
ALL TESTS PASSED
Tests run: 3
tests/ringbuffer_tests PASS
----
RUNNING: ./tests/sarray_tests
./tests/runtests.sh: line 3:  1033 Segmentation fault      $VALGRIND ./$i 2>>  tests/tests.log
ERROR in test tests/sarray_tests: here's tests/tests.log
------
DEBUG tests/ringbuffer_tests.c:60: ----- RUNNING: ./tests/ringbuffer_tests
DEBUG tests/ringbuffer_tests.c:53: 
----- test_create
DEBUG tests/ringbuffer_tests.c:54: 
----- test_read_write
DEBUG tests/ringbuffer_tests.c:55: 
----- test_destroy
DEBUG tests/sarray_tests.c:46: ----- RUNNING: ./tests/sarray_tests
DEBUG tests/sarray_tests.c:39: 
----- test_create
make: *** [tests] Error 1
Run Code Online (Sandbox Code Playgroud)

注意:同样的缺陷似乎不会影响OS X 8构建(这对我自己来说是一个难题).必须在OS X 8版本的构建中修复一个单独的缺陷.具体来说,以下行list_algos.c:

...

inline List *List_merge(List *left, List *right, List_compare cmp)
{
   List *result = List_create();
...
Run Code Online (Sandbox Code Playgroud)

内联函数需要函数原型.更改为以下内容:

...

extern List *List_merge(List *left, List *right, List_compare cmp);
inline List *List_merge(List *left, List *right, List_compare cmp)
{
   List *result = List_create();
...
Run Code Online (Sandbox Code Playgroud)

经过这一次修改后,OS X版本能够make成功完成.