夜影如歌

Qt : macOS平台下开发,Fatal Error with DyLib.md :Library Not Loaded / Image Not Found
#### 问题描述: 操作系统: macOS 10.13 开发环境: Qt 5.11.0 项目结构:...
扫描右侧二维码阅读全文
07
2018/06

Qt : macOS平台下开发,Fatal Error with DyLib.md :Library Not Loaded / Image Not Found

问题描述:

操作系统: macOS 10.13
开发环境: Qt 5.11.0

项目结构:

  • demo_app1:主程序,生成目标路径:$$PWD/bin
  • demo_lib1: 库模块,生成目标路径:$$PWD/lib

demo_app1 依赖 demo_lib1。可在 Qt Creator 环境下构建 Release 版本。:

demo_lib1.pro:

QT       -= gui

TARGET = demo_lib1
TEMPLATE = lib

DESTDIR = $$PWD/lib

DEFINES += DEMO_LIB1_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        demo_lib1.cpp

HEADERS += \
        demo_lib1.h \
        demo_lib1_global.h 

unix {
    target.path = /usr/lib
    INSTALLS += target
}

VERSION = 2.1.0

编译后,生成文件:

2018-06-06_23-47-04.png

demo_app1.pro:

QT += quick
CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

RESOURCES += qml.qrc

VERSION = 2.1.0
DESTDIR = $$PWD/bin

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

LIB_DIR=$$PWD/../demo_lib1/lib
LIBS += -L$${LIB_DIR} -ldemo_lib1.$${VERSION}

编译生成:

2018-06-06_23-51-14.png

此时,双击运行,弹出提示:
2018-06-06_19-51-19.png

单击 Report 查看:

2018-06-06_19-51-42.png

解决过程:

maximo@ https://forum.qt.io/topic/59209/solved-osx-deployment-fatal-error-with-dylib-library-not-loaded-image-not-found/2

https://stackoverflow.com/questions/14888668/how-to-set-dyld-library-path-in-xcode/15106738#15106738

$ cd ~/demo_app1/bin/demo_app1.app/Contents/MacOS
$ ls -l
total 96
-rwxr-xr-x  1 wall-e  staff  23028 Jun  6 19:50 demo_app1
$ ./demo_app1
dyld: Library not loaded: libdemo_lib1.2.dylib
  Referenced from: /Users/wall-e/demo_app1/bin/demo_app1.app/Contents/MacOS/./demo_app1
  Reason: image not found
Abort trap: 6
(同时弹出如双击运行 demo_app1.app 时一样的提示框)
$ otool -L demo_app1

2018-06-06_23-57-25.png

注意到了吗,libdemo_lib1.2.dylib 前面是没有路径的。需要指定路径才能被正常加载。可以指定的路径,这里不选 @rpath 而选择 @loader_path,以指定 libdemo_lib1.2.1.0.dylib 是在 Content/MacOS 目录下查找。可使用如下命令实现:

$ cd ~/demo_lib1/lib
$ cp -r libdemo_lib1.2.1.0.dylib "libdemo_lib1.2.1.0 copy.dylib"
$ install_name_tool -id @loader_path/libdemo_lib1.2.1.0.dylib libdemo_lib1.2.1.0.dylib

使用 BeyondCompare 对比:

2018-06-07_00-07-06.png

说明已经添加了路径。

接下来,修改 demo_app1.pro 工程,在末尾添加:

macx {
        Resources.files += $${LIB_DIR}/libdemo_lib1.$${VERSION}.dylib
        # repeat with Resources.files += blah for anything else you want in this folder
        Resources.path = Contents/MacOS
        QMAKE_BUNDLE_DATA += Resources
}

然后重新编译,用otool重新查看

$ cd ~/demo_app1/bin/demo_app1.app/Contents/MacOS
$ ls -l
total 72
-rwxr-xr-x  1 wall-e  staff    22K Jun  7 00:11 demo_app1
-rwxr-xr-x  1 wall-e  staff   8.2K Jun  7 00:11 libdemo_lib1.2.1.0.dylib

$ otool -L demo_app1

2018-06-07_00-12-25.png

此时,双击 demo_app1.app 可正常运行。

一步到位

为了免去在生成 demo_lib1的库文件后,需要执行 install_name_tool 命令的问题,这里,修改 demo_lib1.pro 以便支持自动写:

( 在demo_lib1.pro 末尾添加 )

macx {
    lib_name = lib$${TARGET}.$${VERSION}.dylib
    QMAKE_POST_LINK += install_name_tool -id @loader_path/$${lib_name} $${DESTDIR}/$${lib_name}
}

思考: 如果 demo_app1 依赖多个lib库,pro该怎么写?
demo_app1.pro 末尾,可以这样写:

假设,demo_app1.pro 依赖的库有: demo_lib1、demo_lib2、 demolib3,库版本都是 2.1.0

uri_lib_depends = demo_lib1 demo_lib2 demo_lib3
macx {
    for (_lib_name, uri_lib_depends){
            _lib_name = lib$${_lib_name}.$${VERSION}.dylib

#            message($$_lib_name)
            Resources.files += $${QF_BUILD_LIB}/$${_lib_name}
            # repeat with Resources.files += blah for anything else you want in this folderå
    }
    Resources.path = Contents/MacOS
    QMAKE_BUNDLE_DATA += Resources
}

QF_BUILD_LIB 为 lib 库导入路径

最后修改:2018 年 06 月 07 日 05 : 47 AM
如果觉得我的文章对你有用,请随意赞赏

发表评论