1. 程式人生 > >caffe_ssd 偶遇編譯bug描述及解決記錄

caffe_ssd 偶遇編譯bug描述及解決記錄

weiliu大神的ssd框架是很好用的,但在伺服器重灌之後,ssd編譯卻出現了奇怪的bug:

 
  1. CXX src/caffe/data_transformer.cpp

  2. In file included from src/caffe/data_transformer.cpp:8:0:

  3. ./include/caffe/data_transformer.hpp:69:24: error: ‘AnnotatedDatum’ does not name a type

  4. void Transform(const AnnotatedDatum& anno_datum,

  5. ^

  6. ./include/caffe/data_transformer.hpp:71:35: error: ‘AnnotationGroup’ was not declared in this scope

  7. RepeatedPtrField<AnnotationGroup>* transformed_anno_vec);

  8. ^

  9. ./include/caffe/data_transformer.hpp:71:50: error: template argument 1 is invalid

  10. RepeatedPtrField<AnnotationGroup>* transformed_anno_vec);

  11. ^

  12. ./include/caffe/data_transformer.hpp:72:24: error: ‘AnnotatedDatum’ does not name a type

  13. void Transform(const AnnotatedDatum& anno_datum,

  14. ^

 
  1. ......

  2.  
  3.  

一步一步來。

error: ‘AnnotatedDatum’ does not name a type

 說明沒找到定義,去看一下  “./include/caffe/data_transformer.hpp:69:24:

 
  1. void Transform(const AnnotatedDatum& anno_datum,

  2. Blob<Dtype>* transformed_blob,

  3. RepeatedPtrField<AnnotationGroup>* transformed_anno_vec);

結論同樣:沒有定義。

grep 一下,看看AnnotatedDatum定義到底在哪,很快,找到:

“caffe/proto/caffe.pb.h”

於是看看這個caffe.pb.h 怎麼來的,發現是make 的第一步

PROTOC src/caffe/proto/caffe.proto

的產物,事實上,caffe.proto--→caffe.pb.h  這個過程是成功的,caffe.pb.h 也包含在路徑之中。

 

那麼問題來了:

CXX src/caffe/data_transformer.cpp找到了標頭檔案caffe.pb.h而且,caffe.pb.h也給了AnnotatedDatum定義,那麼為什麼編譯的時候報錯AnnotatedDatum沒定義(而非找不到caffe.pb.h)????

 

 

經過一系列痛苦的debug,原因在於Makefile 裡面的一句話:

COMMON_FLAGS += $(foreach includedir,$(INCLUDE_DIRS),-isystem $(includedir))

 

注意藍色字部分,

-isystem 是gcc的引數,表示引用路徑,但是但是但是:

If a standard system include directory, or a directory specified with-isystem, is also specified with-I, the -Ioption is ignored. The directory is still searched but as asystem directory at its normal position in the system include chain. This is to ensure that GCC's procedure to fix buggy system headers andthe ordering for theinclude_next directive are not inadvertently changed. If you really need to change the search order for system directories,use the-nostdinc and/or -isystem

 options. 

大意就是-isystem裡面如果和-I裡面的標頭檔案有衝突,會忽略-I!!!!!!!!

 

也就是,如果系統中(比如/usr/local/include)等地方有同名檔案,會不進行本地(比如/home/XXX/caffe/include)的標頭檔案搜尋。

巧合的是,我之前安裝caffe的時候又一次用了cmake,手賤寫了make install。。。。。。於是我係統裡確實有一套基礎caffe環境,和ssd不同。。。。。。

至此,

 

改了幾個字母:-isystem ---->-I

問題解決。

 

然而,這幾個字母卻花了我兩天的時間,雖然不是全在搞這個,但也想想都心痛。