【发布时间】:2019-02-21 10:06:40
【问题描述】:
构建和运行 Mac OS X 应用程序包可以正常工作。甚至使用 rsync 将 .dmg 图像复制到另一台 Mac 并在这台“处女”MacBook 上运行也可以正常工作。将 .dmg 上传到网站、下载并尝试运行程序会激活安全措施,警告用户
由于无法确认开发者的身份,无法打开应用程序。您的安全首选项只允许安装来自 App Store 和已识别开发者的应用程序。 “TestApp”位于磁盘映像“TestApp.dmg”上。火狐下载了这个 今天 10:16 来自 somewebsite.com 的磁盘映像
到目前为止,这是正常行为,但是当尝试使用系统偏好设置中的安全和隐私选项卡打开应用程序时,它会显示相同的消息,之后程序会立即崩溃。 故障转储摘录:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
VM Regions Near 0:
-->
__TEXT 0000000106e23000-00000001072a7000 [ 4624K] r-x/rwx SM=COW bV [/var/folders/9c/_5lswjs174q6xxbf9qs6gqcc0000gn/T/AppTranslocation/659F14AE-09F4-4A1A-84A8-DA6BE86F6F4E/d/TestApp.app/Contents/MacOS/TestApp]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_c.dylib 0x00007fff6ddd5232 strlen + 18
1 Test.app 0x0000000106e52a45 std::__1::char_traits<char>::length(char const*) + 21
2 Test.app 0x0000000106e39d5c std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) + 44
3 Test.app 0x0000000106e7ae04 main + 1492
4 libdyld.dylib 0x00007fff6dd85015 start + 1
直接在终端中运行下载的应用程序包中的可执行文件可以正常工作。
当我更改TestApp.app/Contents/Info.plist 文件中CFBundleExecutable 键的值时,它出奇地工作正常。
这让我相信代码设计有问题,尽管我对在 Mac OS X 上进行开发一点也不熟悉。
使用codesign -dvvvv testApp.app 检查下载但未更改的应用程序包会得到以下结果Info.plist entries=20。更改 Info.plist 后,同一行显示 Info.plist=not bound
更多背景: 我想避免使用 xcode,因为在 Windows 和 Linux 上应该使用相同的构建过程。 我已经使用 CMAKE 构建了一个 C++ 程序并创建了一个应用程序包,如下所示:
add_executable( TestApp MACOSX_BUNDLE ${SOURCES} ${MOC_SRCS} )
target_link_libraries( TestApp ${LIBRARIES} )
set_target_properties(TestApp PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "TestApp")
它依赖于一些外部库,如 QT、OpenCV、boost,可执行文件动态链接到这些库。我将所有必要的 dylib 文件复制到 TestApp.app/Contents/Frameworks 目录中,并使用“otool”和“install_name_tool”更改了可执行文件和库中的路径。然后将以下手动创建的 Info.plist 文件复制到 TestApp.app/Content/Info.plist。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>17D102</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>TestApp</string>
<key>CFBundleIdentifier</key>
<string>abc.testapp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>4.0</string>
<key>CFBundleName</key>
<string>TestApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>9F2000</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>17E189</string>
<key>DTSDKName</key>
<string>macosx10.13</string>
<key>DTXcode</key>
<string>0941</string>
<key>DTXcodeBuild</key>
<string>9F2000</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
然后我使用 '/local/Qt/5.10.1/clang_64/bin/macdeployqt TestApp.app -codesign="Mac Developer: my@account.com (123456)" -dmg -verbose=3' 来复制 QT 的将文件放入包中,更改运行路径,对所有库和包本身进行代码设计并创建 dmg. 运行此程序可以在开发它的 macbook 上运行,当使用 rsync 传输 dmg 时,它可以在其他 mac 上运行。从网站上传和下载时,它不起作用。令人惊讶的是,调整下载的应用程序包的 Info.plist 文件或直接在终端中运行可执行文件仍然有效。
【问题讨论】:
-
为了帮助您调试代码,我们需要查看您的代码。根据堆栈跟踪的猜测, main 中的某些内容正在打印
const char *字符串,但指针为空。我们需要一个minimal reproducible example -
仅基于堆栈跟踪,这确实是一个很好的猜测,但是,在相当多的情况下(见上文),程序运行良好。不使用我手动创建的 Info.plist,而是使用 macdeployqt 生成的解决了这个奇怪的问题。