簡體   English   中英

使用 CMake 構建和分發 MacOS 應用程序

[英]Building and distributing a MacOS application using CMake

我認為這個問題已經被問了很多次,但我找不到適合我的解決方案。

我有一個用於桌面應用程序的 CMake 項目,用 C++ 編寫,使用一些庫(Qt 和 OpenCV)。 我在 Windows 下開發了項目,但我想為 MacOS 構建它。 為此,我使用 brew 安裝了必要的庫,並使用find_package cmake 命令在我的項目中使用它們。

一切正常,但我的問題是我無法在另一台 MacOS 計算機上成功運行我的項目,因為缺少庫(.dylib)。

在 Windows 上,我使用windeployqt ,然后手動將剩余的 opencv 復制到可執行文件夾中,這樣就可以了。 在 MacOS 上,據我了解,情況並非如此,您必須使用install_name_tool來編輯具有正確路徑的可執行文件。

我嘗試使用macdeployqt將所有必要的庫復制到應用程序包( *.app文件夾)並編輯可執行庫路徑。
我遇到的一個問題是,復制到捆綁包中的 OpenCV 庫鏈接到系統安裝的庫。 為了解決這個問題,我編寫了一個在每個 OpenCV 庫上運行install_name_tool的腳本,這解決了這個問題,但我不確定這是不是最好的方法。

不幸的是,我遇到了另一個我無法解決的問題: macdeployqt沒有部署所有必要的框架,並且由於某種原因,缺少 Qt QDBus 框架。

也許我走錯了路? 我以前從未使用過 MacOS,我不確定這是構建桌面應用程序的正確方法。 有沒有可以作為參考的示例項目?

Ps 我沒有使用 XCode,我只是使用 cmake 工具在終端中構建我的項目。

編輯

這是我使用的示例項目。

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(example LANGUAGES CXX)

# find libraries
find_package(OpenCV REQUIRED)
find_package(Qt6 COMPONENTS Widgets Gui OpenGL OpenGLWidgets Multimedia MultimediaWidgets PrintSupport Charts REQUIRED)

add_executable(some_executable)
target_sources(some_executable PRIVATE "main.cpp")

# tel CMake to create a bundle
# see https://doc.qt.io/qt-6/macos-deployment.html
set_target_properties(some_executable PROPERTIES MACOSX_BUNDLE TRUE)

# link libraries
# some opencv libs I use
target_link_libraries(some_executable PRIVATE opencv_core opencv_xfeatures2d opencv_videoio opencv_highgui opencv_video)
# some Qt libs I use
target_link_libraries(some_executable PRIVATE Qt6::Widgets Qt6::Multimedia Qt6::MultimediaWidgets Qt6::PrintSupport Qt6::Charts)

main.cpp

#include <QApplication>
#include <QLabel>
int main(int argc, char** argv) {
    QApplication app(argc, argv);
    QLabel hello;
    hello.setText("Hello There!");
    hello.show();
    return app.exec();
}

deploy.sh

echo Deploying MacOS bundle...

# use this to see the linked libraries
# otool -l some_executable.app/Contents/MacOS/some_executable

# use macreployqt to deploy the necessary libraries and frameworks
macdeployqt some_executable.app

FRAMEWORKS_PATH=some_executable.app/Contents/Frameworks

# wrong: OPENCV_LIB_PATH=/usr/local/Cellar/opencv/4.5.5_2/lib
OPENCV_LIB_PATH=@rpath
OPENCV_VER=405 # <- change this to match the opecv version

echo editing opencv paths...

OPENCV_LIBS=(
"libopencv_calib3d"
"libopencv_core"
"libopencv_dnn"
"libopencv_features2d"
"libopencv_flann"
"libopencv_highgui"
"libopencv_imgcodecs"
"libopencv_imgproc"
"libopencv_ml"
"libopencv_shape"
"libopencv_video"
"libopencv_videoio"
"libopencv_xfeatures2d"
)

replace_opencv_lib_path() {
    # the library to patch
    LIB=$1

    # the linked library
    TO_REPLACE=$2

    install_name_tool -change ${OPENCV_LIB_PATH}/${TO_REPLACE}.${OPENCV_VER}.dylib @executable_path/../Frameworks/${TO_REPLACE}.${OPENCV_VER}.dylib $FRAMEWORKS_PATH/$LIB.${OPENCV_VER}.dylib
}

for lib in ${OPENCV_LIBS[@]}; do
    for lib2 in ${OPENCV_LIBS[@]}; do
        replace_opencv_lib_path $lib $lib2
    done
done

然后我運行這些命令:

# configure the project
cmake .

# build the project
cmake --build .

# deploy
sudo /bin/sh deploy.sh

# create a DMG file we can test on another computer
sudo macdeployqt some_executable.app -dmg

我剛剛發現macdeployqt沒有部署 Qt D-Bus 框架。 要解決該問題,請在 CMake 文件中顯式添加依賴項。

因此,解決方案是使用我發布的代碼,但在CMakeLists.txt中鏈接Qt::DBus

...
find_package(Qt6 COMPONENTS ... DBus REQUIRED)
...
target_link_libraries(some_executable PRIVATE Qt6::DBus)

然后一切正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM