linuxでcmakeでcaffeを静的にコンパイルする場合-static-libstdc++パラメータが無効な問題
以下はcmakeがMakefileファイルを生成してCaffeを静的ライブラリ接続コンパイルするためのshellスクリプトです.
スクリプトでは、cmakeを呼び出してMakefileを生成する際に、libstdc+、libgccを静的ライブラリ形式で接続することを指定するために
この問題は数日困っていたが、
この末尾の
静的コンパイル後、lddはbinのcaffe依存関係を表示し、システムライブラリ以外の動的ライブラリに依存せず、ファイルサイズも28 MBに達した.
[hadoop@t2-centos6 bin]$ ldd ../release/caffe-ssd_linux_x86_64/bin/caffe linux-vdso.so.1 => (0x00007fff8fb58000) libpthread.so.0 =>/lib64/libpthread.so.0 (0x0000003c24600000) librt.so.1 =>/lib64/librt.so.1 (0x0000003c24e00000) libdl.so.2 =>/lib64/libdl.so.2 (0x0000003c24a00000) libm.so.6 =>/lib64/libm.so.6 (0x0000003c25200000) libc.so.6 =>/lib64/libc.so.6 (0x0000003c24200000) /lib64/ld-linux-x86-64.so.2 (0x0000003c23e00000)
しかし、なぜopencvのライブラリがこの問題を引き起こすのか.ずっと分からなかった.
本明細書で貼り付けたスクリプトは、caffeの静的コンパイルに関する完全なスクリプトではありません.コードクラウド(gitee)から取得してください.https://gitee.com/l0km/caffe-static
#!/bin/bash
# cmake caffe-ssd
# author [email protected]
shell_folder=$(cd "$(dirname "$0")";pwd)
. $shell_folder/build_funs
. $shell_folder/build_vars
#
install_path=$SSD_INSTALL_PATH
echo install_path:$install_path
# gflags
gflags_root=$GFLAGS_INSTALL_PATH
exit_if_not_exist "$gflags_root/lib/libgflags.a" "not found $gflags_root/lib/libgflags.a,please build $GFLAGS_PREFIX"
# glog
glog_root=$GLOG_INSTALL_PATH
exit_if_not_exist "$glog_root/lib/libglog.a" "not found $glog_root/lib/libglog.a,please build $GLOG_PREFIX"
# hdf5 cmake
hdf5_cmake_dir=$HDF5_INSTALL_PATH/share/cmake
exit_if_not_exist $hdf5_cmake_dir "not found $hdf5_cmake_dir,please build $HDF5_PREFIX"
exit_if_not_exist $BOOST_INSTALL_PATH "not found $BOOST_INSTALL_PATH,please build $BOOST_PREFIX"
exit_if_not_exist $OPENBLAS_INSTALL_PATH "not found $OPENBLAS_INSTALL_PATH,please build $OPENBLAS_PREFIX"
exit_if_not_exist $PROTOBUF_INSTALL_PATH "not found $PROTOBUF_INSTALL_PATH,please build $PROTOBUF_PREFIX"
# protobuf lib ,
# centos lib64
[ -e "$PROTOBUF_INSTALL_PATH/lib" ] && protobuf_lib=$PROTOBUF_INSTALL_PATH/lib
[ -e "$PROTOBUF_INSTALL_PATH/lib64" ] && protobuf_lib=$PROTOBUF_INSTALL_PATH/lib64
exit_if_not_exist $SNAPPY_INSTALL_PATH "not found $SNAPPY_INSTALL_PATH,please build $SNAPPY_PREFIX"
# lmdb
lmdb_install_root=$LMDB_INSTALL_PATH/usr/local
exit_if_not_exist $lmdb_install_root "not found $lmdb_install_root,please build lmdb"
exit_if_not_exist $LEVELDB_INSTALL_PATH "not found $LEVELDB_INSTALL_PATH,please build $LEVELDB_PREFIX"
# opencv (OpenCVConfig.cmake)
opencv_cmake_dir=$OPENCV_INSTALL_PATH/share/OpenCV
exit_if_not_exist $opencv_cmake_dir "not found $opencv_cmake_dir,please build $OPENCV_PREFIX"
pushd $SOURCE_ROOT/$SSD_FOLDER
clean_folder build.gcc
#mkdir_if_not_exist build.gcc
pushd build.gcc
# OpenBLAS $caffe_source/cmake/Modules/FindOpenBLAS.cmake
export OpenBLAS_HOME=$OPENBLAS_INSTALL_PATH
# lmdb $caffe_source/cmake/Modules/FindLMDB.cmake.cmake
export LMDB_DIR=$lmdb_install_root
# leveldb $caffe_source/cmake/Modules/FindLevelDB.cmake.cmake
export LEVELDB_ROOT=$LEVELDB_INSTALL_PATH
# GLOG_ROOT_DIR $caffe_source/cmake/Modules/FindGlog.cmake
# GFLAGS_ROOT_DIR $caffe_source/cmake/Modules/FindGFlags.cmake
# HDF5_ROOT https://cmake.org/cmake/help/v3.8/module/FindHDF5.html
# BOOST_ROOT,Boost_NO_SYSTEM_PATHS https://cmake.org/cmake/help/v3.8/module/FindBoost.html
# SNAPPY_ROOT_DIR $caffe_source/cmake/Modules/FindSnappy.cmake
# PROTOBUF_LIBRARY,PROTOBUF_PROTOC_LIBRARY... https://cmake.org/cmake/help/v3.8/module/FindProtobuf.html
# OpenCV_DIR https://cmake.org/cmake/help/v3.8/command/find_package.html
$CMAKE_EXE "$(dirs +1)" $CMAKE_VARS_DEFINE -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$install_path \
-DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc" \
-DGLOG_ROOT_DIR=$glog_root \
-DGFLAGS_ROOT_DIR=$gflags_root \
-DHDF5_ROOT=$HDF5_INSTALL_PATH \
-DBOOST_ROOT=$BOOST_INSTALL_PATH \
-DBoost_NO_SYSTEM_PATHS=on \
-DSNAPPY_ROOT_DIR=$SNAPPY_INSTALL_PATH \
-DOpenCV_DIR=$opencv_cmake_dir \
-DPROTOBUF_LIBRARY=$protobuf_lib/libprotobuf.a \
-DPROTOBUF_PROTOC_LIBRARY=$protobuf_lib/libprotoc.a \
-DPROTOBUF_LITE_LIBRARY=$protobuf_lib/libprotobuf-lite.a \
-DPROTOBUF_PROTOC_EXECUTABLE=$PROTOBUF_INSTALL_PATH/bin/protoc \
-DPROTOBUF_INCLUDE_DIR=$PROTOBUF_INSTALL_PATH/include \
-DCPU_ONLY=ON \
-DBLAS=Open \
-DBUILD_SHARED_LIBS=off \
-DBUILD_docs=off \
-DBUILD_python=off \
-DBUILD_python_layer=off \
-DUSE_LEVELDB=on \
-DUSE_LMDB=on \
-DUSE_OPENCV=on
exit_on_error
remove_if_exist $install_path
make -j $MAKE_JOBS install
exit_on_error
popd
rm -fr build.gcc
popd
スクリプトでは、cmakeを呼び出してMakefileを生成する際に、libstdc+、libgccを静的ライブラリ形式で接続することを指定するために
-DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc"
のパラメータが追加するが、実際の使用過程では、USE_OPENCV=on
(すなわちOpenCVを使用するopencvが静的ライブラリコンパイルされている)を指定した場合、コンパイルされたcaffeはlddで見るもlibstdc++に依存することが分かった.soとlibgcc.so、つまり-static-libstdc++ -static-libgcc
無効になりました..USE_OPENCV=off
の場合、正常に静的に接続できます.この問題は数日困っていたが、
.dir
のlinkを比較した.txt(cmake生成)では、USE_OPENCV=on
で生成するlinkが発見された.txtではopencv静的ライブラリに-lstdc++パラメータが自動的に追加されます.の以下はcaffe.binプロジェクトlink.txt(./tools/CMakeFiles/caffe.bin.dir/link.txt)、長すぎて支店を追加しました:/usr/local/bin/g++ -fPIC -Wall -Wno-sign-compare -Wno-uninitialized -O3 -DNDEBUG -static-libstdc++ -static-libgcc -rdynamic CMakeFiles/caffe.bin.dir/caffe.cpp.o -o caffe -Wl,-rpath,:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -Wl,--whole-archive ../lib/libcaffe.a -Wl,--no-whole-archive ../lib/libproto.a
/home/hadoop/tmp/dl/depends/release/boost_linux_x86_64/lib/libboost_system.a
/home/hadoop/tmp/dl/depends/release/boost_linux_x86_64/lib/libboost_thread.a
/home/hadoop/tmp/dl/depends/release/boost_linux_x86_64/lib/libboost_filesystem.a
/home/hadoop/tmp/dl/depends/release/boost_linux_x86_64/lib/libboost_regex.a -lpthread
/home/hadoop/tmp/dl/depends/release/glog_linux_x86_64/lib/libglog.a
/home/hadoop/tmp/dl/depends/release/gflags_linux_x86_64/lib/libgflags.a
/home/hadoop/tmp/dl/depends/release/protobuf_linux_x86_64/lib64/libprotobuf.a -lpthread
/home/hadoop/tmp/dl/depends/release/glog_linux_x86_64/lib/libglog.a
/home/hadoop/tmp/dl/depends/release/gflags_linux_x86_64/lib/libgflags.a
/home/hadoop/tmp/dl/depends/release/protobuf_linux_x86_64/lib64/libprotobuf.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_cpp.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_hl_cpp.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_hl.a /home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_cpp.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_hl_cpp.a
/home/hadoop/tmp/dl/depends/release/hdf5_linux_x86_64/lib/libhdf5_hl.a
/home/hadoop/tmp/dl/depends/release/lmdb_linux_x86_64/usr/local/lib/liblmdb.a
/home/hadoop/tmp/dl/depends/release/leveldb_linux_x86_64/lib/libleveldb.a
/home/hadoop/tmp/dl/depends/release/snappy_linux_x86_64/lib/libsnappy.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/lib/libopencv_highgui.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/liblibjpeg.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/liblibpng.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/liblibtiff.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/liblibjasper.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/libIlmImf.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/lib/libopencv_imgproc.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/lib/libopencv_core.a
/home/hadoop/tmp/dl/depends/release/opencv_linux_x86_64/share/OpenCV/3rdparty/lib/libzlib.a
-lstdc++ -lm -lpthread -lrt
/home/hadoop/tmp/dl/depends/release/OpenBLAS_linux_x86_64/lib/libopenblas.a
-ldl -pthread -lrt
この末尾の
-lstdc++
パラメータが-static-libstdc++ -static-libgcc
を無効にし、-lstdc++
を手動で削除しようとすると、コンパイルが通過し、stdc++、libgccが静的に接続されます.そこでcmakeでMakefileを生成した後、次のコードを追加すると、問題は解決します.# link.txt -lstdc++ , libstdc++ , USE_OPENCV=on ,libstdc++
for file in $(find . -name link.txt)
do
echo "modifing file: $file"
#sed -i -r "s/-lstdc\+\+/ /g" $file
done
静的コンパイル後、lddはbinのcaffe依存関係を表示し、システムライブラリ以外の動的ライブラリに依存せず、ファイルサイズも28 MBに達した.
[hadoop@t2-centos6 bin]$ ldd ../release/caffe-ssd_linux_x86_64/bin/caffe linux-vdso.so.1 => (0x00007fff8fb58000) libpthread.so.0 =>/lib64/libpthread.so.0 (0x0000003c24600000) librt.so.1 =>/lib64/librt.so.1 (0x0000003c24e00000) libdl.so.2 =>/lib64/libdl.so.2 (0x0000003c24a00000) libm.so.6 =>/lib64/libm.so.6 (0x0000003c25200000) libc.so.6 =>/lib64/libc.so.6 (0x0000003c24200000) /lib64/ld-linux-x86-64.so.2 (0x0000003c23e00000)
しかし、なぜopencvのライブラリがこの問題を引き起こすのか.ずっと分からなかった.
本明細書で貼り付けたスクリプトは、caffeの静的コンパイルに関する完全なスクリプトではありません.コードクラウド(gitee)から取得してください.https://gitee.com/l0km/caffe-static