2015-11-15 3 views
0

В настоящее время я действительно очень новичок в C++ и CMake, однако у меня есть программа, которая хочет статически Link ImageMagick, но только ImageMagick.CMake статически Ссылка ImageMagick?

В основном причина мне нужна ImageMagick, которая не поддерживается везде. Я также мог бы клонировать исходный код. В настоящее время мой CMakeList.txt такова:

cmake_minimum_required(VERSION 3.3) 
project(envisia_worker) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

# ImageMagick 
find_package(ImageMagick COMPONENTS Magick++) 

# Nuance 
link_directories("/usr/local/lib/nuance-omnipage-csdk-lib64-19.2") 

# Building 
set(SOURCE_FILES main.cpp) 
add_executable(envisia_worker ${SOURCE_FILES}) 

# Nuance 
include_directories("/usr/local/include/nuance-omnipage-csdk-19.2") 
target_link_libraries(envisia_worker kernelapi recpdf recapiplus) 

# ImageMagick 
include_directories(${ImageMagick_INCLUDE_DIRS}) 
target_link_libraries(envisia_worker ${ImageMagick_LIBRARIES}) 

Однако это будет Свяжите против моих распределений ImageMagick 5. Также я включаю другие библиотеки, они должны остаться dynlib, однако ImageMagick так или иначе должны быть скомпонованы статически, есть ли способ сделать это?

+0

Я не совсем понимаю, что вы хотите. 'однако ImageMagick должен каким-то образом быть связанным статически' - только ** статические библиотеки ** могут быть * статически * связаны с. Можно ли создать «ImageMagick» как набор статических библиотек? Или ваша проблема заключается в том, как сказать 'find_package (ImageMagick)', чтобы найти * свою собственную установку * этого пакета вместо * общесистемного * *? – Tsyvarev

+0

@ Цыварев нет, find_package нашел все, и я мог использовать ImageMagick, однако я подумал, что смогу каким-то образом связать ImageMagick со всеми его зависимостями. Действительно, он действительно имеет отношение к десяткам библиотек и надеется, что каждый дистрибутив имеет правильную версию. Но поскольку я читаю все больше и больше, это не так просто, как я думал, особенно не для ImageMagick –

+0

Итак, вы хотите ** создать исполняемый файл на одной машине и использовать его на другом языке **? И обратите внимание, что связь с некоторыми библиотеками должна использовать их ** пути ** (абсолютные или относительные), потому что вы предоставляете их на другой машине, но связываетесь с некоторыми другими библиотеками (например, с ImageMagick), которые вы хотите быть ** только для имени **, чтобы их можно было найти динамически в каталогах конкретных пакетов? Я просто хочу сделать вопрос более ясным. – Tsyvarev

ответ

1

Вы можете указать RPATH для исполняемого файла, поэтому он будет искать до системных каталогов, когда исполняемый файл будет загружен:

... 
# ImageMagick 
find_package(ImageMagick COMPONENTS Magick++) 

# Deduce directories, where ImageMagick libraries are located 
set(ImageMagick_LIBRARIES_DIRS) 
foreach(lib ${ImageMagick_LIBRARIES}) 
    get_filename_component(dir ${lib} DIRECTORY) 
    list(APPEND ImageMagick_LIBRARIES_DIRS ${dir}) 
    list(REMOVE_DUPLICATES ImageMagick_LIBRARIES_DIRS) 
endforeach() 

# Tell CMake to set RPATH for all *futher* targets. 
set(CMAKE_INSTALL_RPATH ${ImageMagick_LIBRARIES_DIRS}) 

... # Create targets, link them, etc. 

# Install targets 
install(TARGETS envisia_worker DESTINATION <...>) 

Обратите внимание, что только установлены целей получают эффект CMAKE_INSTALL_RPATH переменные.

Построенные цели уже имеют RPATH, указывающие на каждую библиотеку, к которой привязана цель, но такие цели обычно используются только на текущей машине. Это установлено целей, которые должны быть распространяемые другим машинам.

Более подробное описание взаимодействующих CMake и RPATH можно найти here.


Обратите внимание, что, используя абсолютные пути в RPATH для пакетов локальной библиотеки делает ПАКЕТ распространяемого, но не перемещаемый: на других машинах, вам нужно иметь пакет (с его LIBS) в том же месте, где он был установлен на оригинальной машине.

Для макияжа пакета перемещаемого, то есть, чтобы он (с LIBS), чтобы иметь какой-либо путь на другой машине, RPATH для исполняемого файла следует использовать пути, по отношению к $ORIGIN - каталог с самим исполняемым файлом. Но использование этой базы в переменной CMAKE_INSTALL_RPATH более сложно, прочитайте this mailing для получения дополнительной информации.

Смежные вопросы