2014-05-25 26 views
4

我有一個可怕的時間獲取代碼學習C堅硬方式來編譯的Exercise 32Ç編譯錯誤 - 學習C堅硬方式(例32)

我抄逐字代碼從創作者的GitHub repo,甚至克隆上一個新的存儲庫。我已經瀏覽了其他版本庫,除了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 

這是我的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 

我使用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 
+0

list_tests.c引用''並且cc無法找到它,或者它可以找到它,但它是位於其他位置的不同版本。 – MicroVirus

+1

手動嘗試'cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG tests/list_tests.c -o tests/list_tests build/liblcthw.a'。那樣有用嗎? –

+3

在'cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG build/liblcthw.a tests/list_tests.c -o tests/list_tests'嘗試將'build/liblcthw.a'移到末尾 –

回答

8

從GitHub庫下載的練習32碼是特定的BSD系統平臺(也許OS X)。具體而言,BSD系統中存在一些成功構建所需的符號,但這些符號很可能不在(Linux)Ubuntu 12.04系統上。這些措施包括:

mergesort 
heapsort 

儘管如此,庫和單元測試都可以成功編譯,一個單元測試(最終)將要求上述符號除外。如果對以下所示的makefile中的缺陷進行輕微更改,那麼將tests目錄中的單個有問題的測試移動到其他測試可以在(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 

缺陷可以在Makefile找到。這裏是Makefile的有缺陷的部分,作爲下載:

# The Unit Tests 
.PHONY: tests 
tests: CFLAGS += $(TARGET) 
tests: $(TESTS) 
     sh ./tests/runtests.sh 

一個問題是,放置的$(TARGET)build/liblcthw.a值在CFLAGS結束不起作用。這是由於CFLAGS針對編譯器,而不是鏈接器。因此,最終的「測試」目標與圖書館沒有關聯。

另一個問題是至少有一個「測試」應用程序需要一個數學庫。

要解決這些問題,Makefile必須修改爲類似下面的內容:

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

要建立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 
... 

然後,生成文件繼續進行運行測試可執行文件:

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 

注:似乎同樣的缺陷並沒有衝擊的OS X 8版本(這是一個困擾我自己)。在OS X 8版本中必須修復一個單獨的缺陷。具體而言,在list_algos.c以下行:

... 

inline List *List_merge(List *left, List *right, List_compare cmp) 
{ 
    List *result = List_create(); 
... 

內聯函數需要一個函數原型。更改爲以下:

... 

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(); 
... 

這個單一修改後,OS X版本能夠make成功。

+0

@MahonriMoriancumer絕對真棒的答案!這解決了這個問題,我無法構建單元測試並理解其原因。太感謝了! – eb80

+0

用_gcc 4.9.0_和_make 4.0_運行這個,添加'tests:LDLIB + = $(TARGET)'就足夠了。感謝您的詳細解答 – Manbroski

+0

@Manbroski。謝謝,你的解決方案爲我工作。不幸的是Mahonri Moriancumer沒有。用cc運行(Ubuntu 5.3.1-14ubuntu2.1)5.3.1 20160413和Gnu make 4.1。也許Mahonri's與第32章中的測試場景相比會有所不同。無論如何,謝謝!很好的見解。 – jetimms