捆绑应用程序中的dylibs和框架 [英] dylibs and frameworks in bundle app

查看:131
本文介绍了捆绑应用程序中的dylibs和框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天我正在阅读很多有关部署MacOSX应用程序的信息,但我仍然有一些疑问。过去几年,我一直在为MacOSX部署Qt4应用程序,使用Macdeployqt 。现在,mi应用程序使用不属于Qt框架的库:Poppler。



我已经使用Homebrew 安装了poppler-qt4:

  brew install poppler --with-qt4 --enable-xpdf-headers 

使用 macdeployqt 后,我知道我必须使用* install_name_tool *来通过相对路径更改绝对路径。一些dylib还有依赖关系:


  MyApp.app/Contents/MacOS/MyApp:
/usr/local/lib/libpoppler-qt4.4.dylib

/usr/local/lib/libpoppler-qt4.4.dylib:
/ usr / local / Cellar /poppler/0.20.5/lib/libpoppler.28.dylib
/usr/local/lib/libfontconfig.1.dylib
/usr/local/lib/QtCore.framework/Versions/4/QtCore
/usr/local/lib/QtGui.framework/Versions/4/QtGui
/usr/local/lib/QtXml.framework/Versions/4/QtXml


使用 macdeployqt 后,我知道Qt框架已被复制到应用程序包中,如何使用* install_name_tool *?相对路径更改 /usr/local/lib/QtCore.framework/Versions/4/QtCore



是否使用* -headerpad_max_install_names *编译自制的dylib?



有没有一种自动的方法来使用brew?



与* install_name_tool *应该使用什么? @executable_path或@loader_path?



编辑:似乎macdeployqt足够智能部署第三方dylibs,poppler-qt4及其所有依赖项被复制到Applicaciont.app / Frameworks文件夹,并且install_name_tool被自动使用。但是,现在我遇到这个BUG: macdeployqt不复制插件我想这个问题是 qt在poppler-qt4.4的名称。

解决方案

您可以手动更改所有路径,容易,长而痛苦。
我建议使用一个工具为你做:cpack包含在cmake。



无论如何,自10.5以来,你应该使用:@loader_path。请参阅 Dylib



对于MacOS X,以下代码即使使用root用户权限也创建了一个捆绑包,并且正确地复制了homebrew dylib。
但是,您必须检查每个使用homebrew编译的lib是否具有正确的参数。



通常,对于部署来说,最好是手动编译libs 。我有一些自制库(ffmpeg)的问题。但是没有Qt和Boost: - )。

  if(USE_QT5)
qt5_use_modules(MyApp Core OpenGL Sql Multimedia Concurrent)
endif()

#安装东西
set(plugin_dest_dir bin)
set(qtconf_dest_dir bin)
set(APPS\ $ {CMAKE_INSTALL_PREFIX} / bin / MyApp)
if(APPLE)
set(plugin_dest_dir MyApp.app/Contents/)
set(qtconf_dest_dir MyApp.app/Contents/Resources)
set(APPS \ $ {CMAKE_INSTALL_PREFIX} /MyApp.app)
endif(APPLE)
如果(WIN32)
设置(APPS\ $ {CMAKE_INSTALL_PREFIX} /bin/MyApp.exe )
endif(WIN32)

#-------------------------------- ------------------------------------------------
#安装MyApp应用程序,在Apple上,捆绑包位于
#install树的根目录,而在其他平台上,它将进入bin目录。
install(TARGETS MyApp
BUNDLE DESTINATION。COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime


#---------- -------------------------------------------------- --------------------
#通过从qt安装复制目录来安装所需的Qt插件
#可以使用' REGEX...EXCLUDE
install(DIRECTORY$ {QT_PLUGINS_DIR} / imageformats
$ {QT_PLUGINS_DIR} / codecs
$ {QT_PLUGINS_DIR} / phonon_backend
$ {QT_PLUGINS_DIR} / sqldrivers
$ {QT_PLUGINS_DIR} / accessible
$ {QT_PLUGINS_DIR} / bearer
$ {QT_PLUGINS_DIR} / graphicssystems
DESTINATION $ {plugin_dest_dir} / PlugIns
COMPONENT Runtime
FILES_MATCHING
PATTERN* .dylib
PATTERN* _debug.dylibEXCLUDE


#----------------------------------------------- ---------------------------------
#安装qt.conf文件
#这个插入一些cmake代码到安装脚本中写入文件
install(CODE
file(WRITE \\ $ {CMAKE_INSTALL_PREFIX} / $ {qtconf_dest_dir} /qt.conf\\\\ \\)
COMPONENT Runtime



#---------------------- -------------------------------------------------- --------
#使用BundleUtilities获取应用程序工作的所有其他依赖项。
#它需要一个包或可执行文件以及可能的插件,并检查它
#的依赖关系。如果它们不是系统依赖关系,则它们被复制。

#寻找依赖关系的目录
set(DIRS $ {QT_LIBRARY_DIRS} $ {MYAPP_LIBRARIES})

#现在将依赖关系复制到包/包中
#引号是转义的,在安装时使用的变量有$ escaped
#另一种方法是在脚本上执行一个configure_file()并使用install(SCRIPT ...)。
#请注意,图像插件取决于QtSvg和QtXml,并且它们已经复制了
#。

安装(CODE
文件(GLOB_RECURSE QTPLUGINS
\\ $ {CMAKE_INSTALL_PREFIX} / $ {plugin_dest_dir} / plugins / * $ {CMAKE_SHARED_LIBRARY_SUFFIX} \)
set(BU_CHMOD_BUNDLE_ITEMS ON)
include(BundleUtilities)
fixup_bundle(\$ {APPS} \\\ $ {QTPLUGINS} \\$ { DIRS} \)
COMPONENT Runtime


#要创建一个包,可以在Mac OS X $ b上运行cpack -G DragNDrop CPackConfig.cmake $ b#其中CPackConfig.cmake是通过包括CPack
#创建的,然后有办法自定义这个以及
设置(CPACK_BINARY_DRAGNDROP ON)
include(CPack)


Yesterday I was reading a lot about deploying MacOSX applications, but I still have some doubts. I have been deploying Qt4 applications for MacOSX for the past few years using macdeployqt. Now, mi application uses a library that doesn't belong to the Qt framework: Poppler.

I have installed poppler-qt4 using Homebrew :

brew install poppler --with-qt4 --enable-xpdf-headers

After using macdeployqt, I know that I have to use *install_name_tool* to change the absolute paths by relative paths. Some of the dylibs have also dependencies:

MyApp.app/Contents/MacOS/MyApp:
    /usr/local/lib/libpoppler-qt4.4.dylib

/usr/local/lib/libpoppler-qt4.4.dylib:
  /usr/local/Cellar/poppler/0.20.5/lib/libpoppler.28.dylib
  /usr/local/lib/libfontconfig.1.dylib
  /usr/local/lib/QtCore.framework/Versions/4/QtCore
  /usr/local/lib/QtGui.framework/Versions/4/QtGui
  /usr/local/lib/QtXml.framework/Versions/4/QtXml

After using macdeployqt I know that Qt frameworks have been copied inside the app bundle, How can I change /usr/local/lib/QtCore.framework/Versions/4/QtCore with a relative path using *install_name_tool*?

Are homebrew dylibs compiled using *-headerpad_max_install_names*?

Is there an automatic way to do this using brew?

What should I use with *install_name_tool*? @executable_path or @loader_path?

EDIT: It seems that macdeployqt is smart enough to deploy third party dylibs, poppler-qt4 and all its dependencies are copied to the Applicaciont.app/Frameworks folder, and install_name_tool is used automatically. BUT, now I am suffering this BUG : macdeployqt not copying plugins I suppose that the problem is "qt" on the name of poppler-qt4.4.

解决方案

You can change by hand all the paths but it is error-prone, long and painful to do. What I suggest is to use a tool to do it for you: cpack included with cmake.

Anyways since 10.5 you should use: @loader_path. See Dylib.

For MacOS X the following code creates a bundle and copy properly homebrew dylib even with root permissions. However, you will have to check that every lib compiled with homebrew had the right parameters.

Usually, for deployement it is better to compile by hand the libs. I had some problems with homebrew libs (ffmpeg). But not Qt nor Boost :-).

if( USE_QT5 )
     qt5_use_modules( MyApp Core OpenGL Sql Multimedia Concurrent )
endif()

# Install stuff
set( plugin_dest_dir bin )
set( qtconf_dest_dir bin )
set( APPS "\${CMAKE_INSTALL_PREFIX}/bin/MyApp" )
if( APPLE )
    set( plugin_dest_dir MyApp.app/Contents/ )
    set( qtconf_dest_dir MyApp.app/Contents/Resources )
    set( APPS "\${CMAKE_INSTALL_PREFIX}/MyApp.app" )
endif( APPLE )
if( WIN32 )
    set( APPS "\${CMAKE_INSTALL_PREFIX}/bin/MyApp.exe" )
endif( WIN32 )

#--------------------------------------------------------------------------------
# Install the MyApp application, on Apple, the bundle is at the root of the
# install tree, and on other platforms it'll go into the bin directory.
install( TARGETS MyApp
    BUNDLE DESTINATION . COMPONENT Runtime
    RUNTIME DESTINATION bin COMPONENT Runtime
)

#--------------------------------------------------------------------------------
# Install needed Qt plugins by copying directories from the qt installation
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
install( DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
    "${QT_PLUGINS_DIR}/codecs"
    "${QT_PLUGINS_DIR}/phonon_backend"
    "${QT_PLUGINS_DIR}/sqldrivers"
    "${QT_PLUGINS_DIR}/accessible"
    "${QT_PLUGINS_DIR}/bearer"
    "${QT_PLUGINS_DIR}/graphicssystems"
    DESTINATION ${plugin_dest_dir}/PlugIns
    COMPONENT Runtime
    FILES_MATCHING
    PATTERN "*.dylib"
    PATTERN "*_debug.dylib" EXCLUDE
)

#--------------------------------------------------------------------------------
# install a qt.conf file
# this inserts some cmake code into the install script to write the file
install( CODE "
    file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"\")
    " COMPONENT Runtime
)


#--------------------------------------------------------------------------------
# Use BundleUtilities to get all other dependencies for the application to work.
# It takes a bundle or executable along with possible plugins and inspects it
# for dependencies.  If they are not system dependencies, they are copied.

# directories to look for dependencies
set( DIRS ${QT_LIBRARY_DIRS} ${MYAPP_LIBRARIES} )

# Now the work of copying dependencies into the bundle/package
# The quotes are escaped and variables to use at install time have their $ escaped
# An alternative is the do a configure_file() on a script and use install(SCRIPT  ...).
# Note that the image plugins depend on QtSvg and QtXml, and it got those copied
# over.

install( CODE "
    file(GLOB_RECURSE QTPLUGINS
      \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
    set(BU_CHMOD_BUNDLE_ITEMS ON)
    include(BundleUtilities)
    fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
    " COMPONENT Runtime
)

# To Create a package, one can run "cpack -G DragNDrop CPackConfig.cmake" on Mac OS X
# where CPackConfig.cmake is created by including CPack
# And then there's ways to customize this as well
set( CPACK_BINARY_DRAGNDROP ON )
include( CPack )

这篇关于捆绑应用程序中的dylibs和框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆