1, Introduction
The graphical interface packaged on MacOS must be created from the Bundle. This Bundle is like Apk, which contains code, libraries, resource files and so on.
If you create a QT project by yourself and use a. pro file, this file will have the Bundle attribute. To be safe, you can also add the following:
CONFIG+=app_bundle
If there is no Bundle, the. app to be used later will not be compiled. To use CMakeLists.txt, you need to configure the Bundle yourself:
add_executable(example # The important thing is the following line MACOSX_BUNDLE ${SRC_LIST} ${SRC_COMMON_LIST} ${SRC_TEST_LIST} ${QRC_FILES} main.cpp ) # These are version numbers and names set_target_properties(example PROPERTIES BUNDLE True MACOSX_BUNDLE_GUI_IDENTIFIER example MACOSX_BUNDLE_BUNDLE_NAME "example" MACOSX_BUNDLE_BUNDLE_VERSION "0.1" MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1" # This plist.in is extracted from QT, mainly for macos application configuration. I also copied it below MACOSX_BUNDLE_INFO_PLIST ./MacOSXBundleInfo.plist.in )
MacOSXBundleInfo.plist.in :
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> <key>CFBundleGetInfoString</key> <string>${MACOSX_BUNDLE_INFO_STRING}</string> <key>CFBundleIconFile</key> <string>${MACOSX_BUNDLE_ICON_FILE}</string> <key>CFBundleIdentifier</key> <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleLongVersionString</key> <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> <key>CFBundleName</key> <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> <key>CSResourcesFileMapped</key> <true/> <key>NSHumanReadableCopyright</key> <string>${MACOSX_BUNDLE_COPYRIGHT}</string> </dict> </plist>
2, Pack
First select the Release version in QT, compile it, and then enter the build directory. Normally, you will see an example.app file in the build directory. If not, there is only one executable file, that is, the Bundle is not set.
First:
~/Qt/5.15.2/clang_64/bin/macdeployqt example.app
This project will copy the resource files and three-party libraries used by example to example.app/Contents /, and then the three-party libraries will be placed under example.app/Contents/Frameworks /.
Specific to our application, it will copy some third-party libraries to Frameworks:
Then the important thing is to adjust the dependency structure of the library. Use "otool -L" to see the dependency of the program or other libraries:
For example, look at the example:
otool -L example.app/Contents/MacOS/example
The paths of its dependent libraries will be listed. If some third-party libraries, such as libopus.dylib, point to / usr/lib /, they must be manually changed. Otherwise, when running, they will go to the system directory and find problems in other people's environment. If they are public libraries, such as libc++.1.dylib, there will be no problem.
The above figure shows the library dependency of example. It is still relatively perfect after the implementation of macdeployqt. There is no problem with the path and there is no need to change it.
However, if you package directly in this way, you may still report an error after running dmg:
This problem has been perplexed for a long time. It is clear that the paths listed above are correct, but they always go to the system path to find the solution. Later, I read the document that otool can also see the library dependencies, and then listed libavformat.58.dylib in the figure:
otool -L example.app/Contents/Frameworks/libavformat.58.dylib
I found that some of the paths here are systematic, so I have to change them one by one
install_name_tool -change "/usr/local/Cellar/ffmpeg/4.4_1/lib/libswresample.3.dylib" "@executable_path/../Frameworks/libswresample.3.dylib" example.app/Contents/Frameworks/libavformat.58.dylib
This install_name_tool is specially used by MacOS to change the dependency library.
Many other libraries are like this. They have to be changed back and repackaged after the change:
~/Qt/5.15.2/clang_64/bin/macdeployqt example.app -dmg
In this way, the typed package can be used in other MAC computers.