2016-04-29 14 views
1

依存関係を決定された相対パスで探す実行可能ファイルを作成します。言い換えれば、私は2つの要素を含むzipを配布したい:実行可能ファイルと共有ライブラリを持つフォルダ。実行可能ファイルは実行時にそれらの共有ライブラリを見つけることができなければなりません。私は今の 依存関係を持つ移植可能な実行可能ファイルを作成する

をテストしてみた何

、私はcmakeでコンパイルされたプロジェクトを持っています。私はcmakeのコマンドfind_libraryを使用してabsを探しています。依存関係へのパス。ここで

はCMakeLists.txtファイルです:

cmake_minimum_required(VERSION 2.8) 
project(flowers) 

find_library(VFC_LIB1 NAMES opencv_calib3d PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib) 
find_library(VFC_LIB2 NAMES opencv_core PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib) 
... 
find_library(VFC_LIB16 NAMES opencv_videostab PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib) 

SET(VFC_LIBS ${VFC_LIB1} ${VFC_LIB2} ... ${VFC_LIB16}) 

SET(VFC_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/opencv) 

IF (VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16) 

    include_directories(${VFC_INCLUDE}) 
    include_directories(FlowersDetector NeuronalNet) 
    add_executable(flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp) 
    add_definitions(-std=c++11) 
    add_definitions(-D_DEBUG) # TODO remove this for release 
    target_link_libraries(flowers ${VFC_LIBS}) 

ELSE (VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16) 

    MESSAGE(FATAL_ERROR "OpenCV libraries not found") 

ENDIF(VFC_LIB1 AND VFC_LIB2 AND ... AND VFC_LIB16) 

...は、残りの部分は以前と同じであることを示しているが、シーケンス番号を変ります。例えば

xは3から15

であるalwais VFC_LIBxあるVFC_LIB1 AND VFC_LIB2 ... AND VFC_LIB16手段、probem

問題は、(私はそれを読んだ)find_library絶対パスを取得するために使用されていることですので、実行可能ファイルを他のコンピュータにコピー&ペーストしても、それを実行することはできません。

私が必要とするのは、相対パスであるまたは同等のソリューションを持つライブラリを見つけることです。

EDIT

私は「その中に」すべてのライブラリとの「大」の実行可能ファイルを作成しようとしています。その目的のために、私は静的ライブラリをリンクする必要があることを読んだ。私は静的ライブラリを構築し、再コンパイルOpenCVの(今私は* .Aファイルプラス* .soのファイルを持っているを持っている

私はこれらの静的ライブラリを追加するCMakeLists.txtを変更されています。

cmake_minimum_required(VERSION 2.8) 
project(flowers) 
find_package(OpenCV REQUIRED) 

SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") 
SET(BUILD_SHARED_LIBRARIES OFF) 
SET(CMAKE_EXE_LINKER_FLAGS "-static") 

include_directories(${OpenCV_INCLUDE_DIRS}) 
include_directories(FlowersDetector NeuronalNet) 
add_executable(flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp) 
add_definitions(-std=c++11) 
add_definitions(-D_DEBUG) 
target_link_libraries(flowers ${OpenCV_LIBS}) 

cmakeコマンドは、[OK]を実行しますが、私はmake私は多くのエラーを取得プロジェクトにしようとすると、実際には、それが唯一の誤りのように見えるが、数回に答えた。このエラーは、次のとおりです。ここでstatically linked applications requires at runtime the shared libraries from the glibc version used for linking

は避けて、エラーのリストです似たようなもの:(もし完全なリストが役に立つとすれば教えてください)

Linking CXX executable flowers 

/usr/bin/ld: cannot find -latk-1.0 

/usr/bin/ld: cannot find -lgdk_pixbuf-2.0 

/usr/local/lib/libopencv_core.a(opencl_core.cpp.o): In function `(anonymous namespace)::opencl_fn14<41, int, _cl_command_queue*, _cl_mem*, unsigned int, unsigned long const*, unsigned long const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, void const*, unsigned int, _cl_event* const*, _cl_event**>::switch_fn(_cl_command_queue*, _cl_mem*, unsigned int, unsigned long const*, unsigned long const*, unsigned long const*, unsigned long, unsigned long, unsigned long, unsigned long, void const*, unsigned int, _cl_event* const*, _cl_event**)': 

opencl_core.cpp:(.text._ZN12_GLOBAL__N_111opencl_fn14ILi41EiP17_cl_command_queueP7_cl_memjPKmS6_S6_mmmmPKvjPKP9_cl_eventPSA_E9switch_fnES2_S4_jS6_S6_S6_mmmmS8_jSC_SD_+0x1c0): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 

/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_gid_name': 

(.text+0x11a7): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 

[And many similar errors] 

collect2: error: ld returned 1 exit status 

CMakeFiles/flowers.dir/build.make:143: recipe for target 'flowers' failed 

make[2]: *** [flowers] Error 1 

CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/flowers.dir/all' failed 

make[1]: *** [CMakeFiles/flowers.dir/all] Error 2 

Makefile:76: recipe for target 'all' failed 

make: *** [all] Error 2 

私は静的ライブラリ(* .aという)との再インストールOpenCVのをテストしてみたデフォルトのOpenCVのCMakeListsを使用するようにEDIT 2

cmake_minimum_required(VERSION 2.8) 
project(flowers) 
find_package(OpenCV REQUIRED) 

include_directories(${OpenCV_INCLUDE_DIRS}) 
include_directories(FlowersDetector NeuronalNet) 
add_executable(flowers FlowersDetector/Flowers.cpp FlowersDetector/FlowersDetector.cpp) 
add_definitions(-std=c++11) 
add_definitions(-D_DEBUG) 
target_link_libraries(flowers ${OpenCV_LIBS}) 

私がすることができますでも、私はプログラムを実行することができますが、プログラムは、私は次のエラーを持っている画像を表示しようとすると、すべてをコンパイルします。

OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /media/ubuntu/67803d44-978a-493e-bdfb-5730e7e9f5a8/opencv-3.1.0/modules/highgui/src/window.cpp, line 527 
terminate called after throwing an instance of 'cv::Exception' 
    what(): /media/ubuntu/67803d44-978a-493e-bdfb-5730e7e9f5a8/opencv-3.1.0/modules/highgui/src/window.cpp:527: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvNamedWindow 

Aborted (core dumped) 

私が持っていますapt-get installlibgtk2.0-devpkg-configと一緒にインストールされ、また、私はATK lib(http://www.linuxfromscratch.org/blfs/view/svn/x/atk.htmlから)をダウンロードしてインストールしました。

その後、再起動してcmakemakeを再実行しました。プログラムを実行すると、エラーは解決しません。

+0

「編集」セクションのエラーは簡単に検出されます。これは、静的リンケージは 'getgrgid_r'を使用するアプリケーションには適していないことを意味します。この関数は*ターゲットマシン固有のものです(たとえば、そのマシンのシステム管理者が変更することができます)。 – Tsyvarev

+0

警告です。私はエラーが 'atk-1.0'と' gdk-pixbuf'がないと思います。私はすでにそれらをインストールしようとしましたが、エラーが続く。 – Dan

+0

あなたのビルドマシンに '-dv'バージョンの' atk-1.0'と 'gdk-pixbuf'がインストールされていますか? –

答えて

2

Linux実行可能ファイルでは、RPATHメカニズムを使用してライブラリへのパスに関する情報を格納します。この情報は、実行可能ファイルをメモリにロードするときにリンカによって使用されます。

ライブラリへのメイクパスの場合の特別なパスコンポーネント$ORIGINが存在し、実行可能ファイルでディレクトリに評価されます。 CMakeので

は、構築された実行可能ファイルのセットRPATHのために、変数 CMAKE_INSTALL_RPATH使用:

# sets RPATH for *install*ed files 
set(CMAKE_INSTALL_RPATH "\$ORIGIN/lib") # Note CMake escaping aroung '$' sign. 
# *built* files will also used RPATH which has been set before 
set(CMAKE_BUILD_WITH_INSTALL_RPATH on) 

# Use 'find_library' calls. They return absolute paths needs for *link* stage. 
find_library(...) 
... 
set(VFC_LIBS ...) 
# Create executable and link it using variables filled by 'find_library' 
add_executable(flowers ...) 
target_link_libraries(flowers ${VFC_LIBS}) 

を今、あなたが移動する(またはインストール)実行可能ファイルをいくつかのディレクトリ<dir>にし、ディレクトリ<dir>/lib/へのすべてのライブラリは、実行ファイルを実行することができた場合。

CMakeでのRPATH処理の詳細については、CMake wikiを参照してください。

0

実行可能ファイルを実行する前にライブラリの検索パスを設定する方法が必要です。 Linux/Unixでは、最も簡単な解決策は、それに応じてLD_LIBRARY_PATHを設定するシェルスクリプトです。 Windowsにはおそらく同様の仕組みがありますが、私はその経験がありません。

どちらの場合でも、CMakeはプログラムとライブラリの構築にのみ役立ちますが、他のコンピュータ上のものを見つけることはできません。

0

これはあなたの質問に対する正確な答えではありませんが、あなたの特定のシナリオでは、実行時にライブラリをロードして、パスの混乱と間違ったライブラリのロードを回避します。

Linux/Macの場合、dlopen()、Windowsの場合はLoadLibrary()で行うことができます。

+1

私はあなたが 'dlopen()'を意味していると思います。通常、固定依存関係ではなく、オプションの追加項目やプラグインに使用されます。 – Useless

+0

はい、正しいです。 –

関連する問題