0%

OSX开发记录

环境安装

  • 这里没有使用AppleBox,参照了OSX-KVM使用qemu-system-x86_64安装一个Virtual Hackintosh系统来做开发.

安装Xcode

  • Xcode需要apple ID登录后下载.

安装Homebrew

1
~$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 brew install nghttp2
Updating Homebrew...
fatal: Could not resolve HEAD to a revision
==> Searching for similarly named formulae...
Error: No similarly named formulae found.
Error: No available formula or cask with the name "nghttp2".
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching taps on GitHub...
Error: No formulae found in taps.
lcy@lcys-iMac-Pro ~ % git -C $(brew --repository homebrew/core) checkout master
Updating files: 100% (5923/5923), done.
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'

安装依赖库

1
~$ brew install nghttp2 nopoll  rapidjson pkg-config

编译源码到库

  • 安装编译时要用的工具.

    1
    ~$ brew install autoconf automake libtool
  • 这里以protobuf为例

    1
    2
    3
    4
    5
    6
    7
    ~$ git clone -b v2.6.0 --depth=1 https://github.com/protocolbuffers/protobuf
    ~$ cd protobuf && ./autogen.sh
    ~$ mkdir build && cd build && ../configure CC=clang CXX=clang++ CXXFLAGS="-std=c++11 -stdlib=libc++ -O3 -g" \
    LDFLAGS="-stdlib=libc++" LIBS="-lc++ -lc++abi" \
    --libdir=/usr/local/protobuf --includedir=/usr/local/protobuf/include --with-zlib && \
    make && sudo make install
    ~$
  • 安装appdmg打包脚本

    1
    2
    ~$ brew install node
    ~$ npm install appdmg -g

库版本不兼容的问题

  • 库版本不兼容的问题,因为程序是在Catalina 10.15.17编译构建的,而且通过brew安装的二进制库,都是根据系统版本(Catalina)下载的,下面错误,是在High Sierra 10.13.17下去运行,出现下面错误,这两个系统版本不兼容.
1
2
3
4
5
6
7
	dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin
Referenced from: /Applications/MyApp.app/Contents/MacOS/./../Frameworks/libssl.1.1.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: ____chkstk_darwin
Referenced from: /Applications/MyApp.app/Contents/MacOS/./../Frameworks/libssl.1.1.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
  • 处理上述问题,必须从源码去编译相应的依赖库,指定export MACOSX_DEPLOYMENT_TARGET=10.12变量,在Qt5工程配置是QMAKE_MACOSX_DEPLOYMENT_TARGET变量.

错误记录

签名权限错误

  • Running codesign over SSH with a new key

  • 必须在OSX图形系统内,使用termiator运行签名.下面是通过SSH运行codesign所出现的错误.

    1
    2
    3
    Error: Command failed: codesign --verbose --sign Developer ID Application: My Company Technology Co. Ltd. (XXXXXXXX) /Users/tuser/dailybuild_mac/felo-client-mac-2021.19.137.dmg
    /Users/tuser/dailybuild_mac/felo-client-mac-2021.19.137.dmg: errSecInternalComponent

  • 通过下面操作终端(shell)导入签名证书.再试试看,再尝试通过SSH去签名,看是否成功.

    1
    2
    3
    ~$ sudo security import developer_id.p12 -k /Library/Keychains/System.keychain -P "<your password>" -T /usr/bin/codesign
    # must run below in the shell.
    ~$ security unlock-keychain
  • 下面这个错误也是类似,只是现在Linux下.QT程序内调用root权限,通过远程ssh -X运行的GUI程序会有下面错误,而在它的本机上面确不会,如,使用pkexec运行,会调出一个输入密码的窗口.

    1
    Error creating textual authentication agent: Error opening current controlling terminal for the process (`/dev/tty'): No such device or address

打包错误

  • 下面的错误,要确认主工程内的info.plist文件里的CFBundleExecutable,CFBundleName节点值,是否与bundle名称对应,是否与主工程.pro里的TARGET对应.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$ macdeployqt output/myappqt.app
ERROR: Could not find bundle binary for "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
WARNING:
WARNING: Could not find any external Qt frameworks to deploy in "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
WARNING: Perhaps macdeployqt was already used on "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app" ?
WARNING: If so, you will need to rebuild "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app" before trying again.
Empty filename passed to function
ERROR: Could not find bundle binary for "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip: can't open file: (No such file or directory)\n"
ERROR: ""

  • macdeployqt错误

    1
    2
    ERROR: no file at “/usr/local/opt/libiodbc/lib/libiodbc.2.dylib”
    ERROR: no file at “/Applications/Postgres.app/Contents/Versions/9.6/lib/libpq.5.dylib”
  • 上面错误是缺失两个依赖的库,须要安装下面支持

    1
    2
    3
    4
    5
    6
    ~$ brew install libiodbc postgres

    ~$ sudo mkdir -pv /Applications/Postgres.app/Contents/Versions/9.6
    ~$ sudo ln -svf /usr/local/Cellar/postgresql/13.3/lib /Applications/Postgres.app/Contents/Versions/9.6
    /Applications/Postgres.app/Contents/Versions/9.6/lib -> /usr/local/Cellar/postgresql/13.3/lib

  • 不能加载插件的错误,如果不是从终端(shell)打开目标程序,就表显为程序闪退.终端打开运行显示如下:

    1
    2
    3
    4
    5
    qt.qpa.plugin: Could not load the Qt platform plugin "cocoa" in "" even though it was found.
    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

    Available platform plugins are: cocoa.

  • 上面错误信息,只是初步定位了错误,如果是在Linux下,上面错误基本是因为文件不存造成.这里打开export QT_DEBUG_PLUGINS=1,查看如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Got keys from plugin meta data ("cocoa")
    QFactoryLoader::QFactoryLoader() checking directory path "/Applications/MyApp.app/Contents/MacOS/platforms" ...
    Cannot load library /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: (dlopen(/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib, 133): no suitable image found. Did find:
    /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: code signature in (/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.)
    QLibraryPrivate::loadPlugin failed on "/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib" : "Cannot load library /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: (dlopen(/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib, 133): no suitable image found. Did find:\n\t/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: code signature in (/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.)"
    qt.qpa.plugin: Could not load the Qt platform plugin "cocoa" in "" even though it was found.
    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

    Available platform plugins are: cocoa.

    Abort trap: 6

  • 如上所示,在OSX下出现的Could not load the Qt platform plugin是因为文件未签名造成的.使用下面方法尝试处理.

    1
    ~$ codesign -f -s "Mac Developer: 你的开发者邮箱" /usr/local/opt/*/lib/*.dylib

签名问题

  • 检验签是否正确

    1
    2
    3
    ~$ spctl -a -t exec -vv /Applications/MyApp.app
    /Applications/MyApp.app: nested code is modified or invalid

  • 查看具体签名错误详情

    1
    2
    3
    4
    5
    ~$ codesign --verify --deep --verbose dmg_root/MyApp.app
    dmg_root/MyApp.app: nested code is modified or invalid
    In subcomponent: /Users/user/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/dmg_root/MyApp.app/Contents/Frameworks/QtWebEngineCore.framework
    file modified: /Users/user/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/dmg_root/MyApp.app/Contents/Frameworks/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app

  • 签名后,检验将要打包的bundle目录签名情况,直到出现下面这样正确为止.

    1
    2
    3
    4
    ~$ codesign --verify --deep --verbose dmg_root/MyApp.app
    dmg_root/MyApp.app: valid on disk
    dmg_root/MyApp.app: satisfies its Designated Requirement

  • 如果按上述签名成,但是其它机器上安装成功,运行时确崩溃了,有些系统会有DiagnosticReports,有些是直接闪退.下面DiagnosticReports的错误,关键信息是EXC_BAD_ACCESS (Code Signature Invalid),__TEXT字段处是指向libcrypto.1.1,可以对libcrypto.1.1路径的文件进行签名校验查看.用户程序crash出错的路径是在/Users/<username>/Library/Logs/DiagnosticReports下面.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Time Awake Since Boot: 12000 seconds

System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x0000000106f3a000
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x106f3a000:
shared memory 0000000106f36000-0000000106f3a000 [ 16K] r--/r-- SM=SHM
--> mapped file 0000000106f3a000-0000000106f3c000 [ 8K] r--/r-- SM=PRV Object_id=4f872dd9
__TEXT 0000000106f3d000-0000000107165000 [ 2208K] r-x/rwx SM=COW /Applications/MyApp.app/Contents/Frameworks/libcrypto.1.1.dylib

Application Specific Information:
dyld: in dlopen()
/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib

  • 下面要是目标程序的未完整签名造成的.__TEXT指向当前系统的/usr/lib/dyld.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x0000000109bed000
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x109bed000:
shared memory 0000000109be5000-0000000109bed000 [ 32K] r--/r-- SM=SHM
--> mapped file 0000000109bed000-0000000109da9000 [ 1776K] r--/r-- SM=PRV Object_id=4f872dd9
__TEXT 000000010a61a000-000000010a6ac000 [ 584K] r-x/r-x SM=COW /usr/lib/dyld
  • OSX编译链接的错误问题, 是因为缺少了这个架构的库文件
    1
    2
    3
    4
    5
    6
    7

    Undefined symbols for architecture x86_64:
    "_iconv_ostream_create", referenced from:
    -exported_symbol[s_list] command line option
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

OSX命令行操作

重启服务

1
2
lcy@lcys-iMac-Pro ~ % sudo launchctl stop com.openssh.sshd
lcy@lcys-iMac-Pro ~ % sudo launchctl start com.openssh.sshd
  • 或者
1
2
lcy@lcys-iMac-Pro ~ %  sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
lcy@lcys-iMac-Pro ~ % sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

使用apple脚本开启远程管理(VNC桌面访问)

1
2
3
4
5
6
7
8
#!/bin/zsh
osascript -e "do shell script \"
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -allUsers -privs -all
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvnclegacy -vnclegacy yes
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvncpw -vncpw 1234test
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -restart -agent -console
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate
\" with administrator privileges"
  • osascript是调起一个图形授权窗口,类似于终端的sudo,在Windows下就类似是UAC窗体,在Linux下就是调用pkexec获取sudo权限.

Command Line 修改配置(defaults)

  • 枚举出所有的可配置域.

    1
    2
    3
    sudo defaults domains
    com.apple.AppleMultitouchMouse, com.apple.AppleMultitouchTrackpad, com.apple.CoreBrightness, com.apple.CoreGraphics, com.apple.CrashReporterSupportHelper, com.apple.MobileAsset, com.apple.SSMenuAgent, com.apple.SoftwareUpdate, com.apple.UserAccountUpdater, com.apple.WirelessRadioManager.debug, com.apple.airplay, com.apple.awdd.persistent, com.apple.bluetoothd, com.apple.corecaptured, com.apple.coreduetd, com.apple.das.fairscheduling, com.apple.driver.AppleBluetoothMultitouch.mouse, com.apple.driver.AppleBluetoothMultitouch.trackpad, com.apple.driver.AppleHIDMouse, com.apple.dt.xcodebuild, com.apple.icloud.findmydeviced, com.apple.icloud.searchpartyd, com.apple.java.util.prefs, com.apple.loginwindow, com.apple.mediaremote, com.apple.mediaremoted, com.apple.rtcreporting, com.apple.security.ctkd-db, com.apple.systempreferences, com.apple.systemstats.microstackshot, com.apple.tailspin, com.apple.universalaccess, com.apple.xpc.activity2, com.oracle.javadeployment, systemmigrationd

  • 查看一个域的配置.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ~$ sudo defaults export com.apple.systempreferences -
    <?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>AttentionPrefBundleIDs</key>
    <dict>
    <key>com.apple.preferences.softwareupdate</key>
    <integer>1</integer>
    </dict>
    </dict>
    </plist>

  • 查看一个文件的配置.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    ~$ sudo defaults export /Library/Preferences/com.apple.RemoteManagement.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>-bool</key>
    <string>no</string>
    <key>ARD_AllLocalUsers</key>
    <true/>
    <key>ARD_AllLocalUsersPrivs</key>
    <integer>1073742079</integer>
    <key>AllowSRPForNetworkNodes</key>
    <false/>
    <key>DisableKerberos</key>
    <false/>
    <key>LoadRemoteManagementMenuExtra</key>
    <true/>
    <key>ScreenSharingReqPermEnabled</key>
    <false/>
    <key>VNCLegacyConnectionsEnabled</key>
    <true/>
    <key>allowInsecureDH</key>
    <true/>
    </dict>
    </plist>
  • 读取域内的一个键值

    1
    2
    sudo defaults read /Library/Preferences/com.apple.RemoteManagement.plist ARD_AllLocalUsers
    1
  • 写入一个键值

    1
    sudo defaults write /Library/Preferences/com.apple.RemoteManagement.plist RestoreMachineState -bool no

keychain密码访问SUDO

查找OSX的服务运行参数

1
2
~$ launchctl list | grep "RemoteDesktop"
66152 -9 com.apple.RemoteDesktop.agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
~$ launchctl print system/com.apple.remotemanagementd
com.apple.remotemanagementd = {
active count = 0
copy count = 0
one shot = 0
path = /System/Library/LaunchDaemons/com.apple.remotemanagementd.plist
state = waiting

program = /System/Library/PrivateFrameworks/RemoteManagement.framework/remotemanagementd
default environment = {
PATH => /usr/bin:/bin:/usr/sbin:/sbin
}

environment = {
XPC_SERVICE_NAME => com.apple.remotemanagementd
}

domain = com.apple.xpc.launchd.domain.system
minimum runtime = 10
exit timeout = 5
runs = 0
successive crashes = 0
last exit code = (never exited)

semaphores = {
provides events => 1
}

event triggers = {
com.apple.remotemanagement.cloudConfigAvailable => {
keepalive = 0
service = com.apple.remotemanagementd
stream = com.apple.distnoted.matching
monitor = com.apple.UserEventAgent-System
descriptor = {
"Name" => "CPCloudConfigIsMDMv2Notification"
}
}
}

endpoints = {
"com.apple.remotemanagementd" = {
port = 0x1d703
active = 0
managed = 1
reset = 0
hide = 0
}
"com.apple.aps.remotemanagementd.http.apns-dev" = {
port = 0x1d803
active = 0
managed = 1
reset = 0
hide = 0
}
"com.apple.aps.remotemanagementd.http.apns-prod" = {
port = 0x18303
active = 0
managed = 1
reset = 0
hide = 0
}
}

dynamic endpoints = {
}

pid-local endpoints = {
}

instance-specific endpoints = {
}

event channels = {
"com.apple.distnoted.matching" = {
port = 0x18403
active = 0
managed = 1
reset = 0
hide = 0
}
}

sockets = {
}

instances = {
}

spawn type = background
spawn role = (null)
jetsam priority = 3
jetsam memory limit (active, soft) = 15 MB
jetsam memory limit (inactive, soft) = 15 MB
jetsamproperties category = daemon
jetsam thread limit = 32
cpumon = default

properties = {
partial import = 0
launchd bundle = 0
xpc bundle = 0
keepalive = 0
runatload = 0
low priority i/o = 0
low priority background i/o = 0
dataless file mode = 0
legacy timer behavior = 0
exception handler = 0
multiple instances = 0
supports transactions = 1
supports pressured exit = 1
supports idle hysteresis = 0
enter kdp before kill = 0
wait for debugger = 0
app = 0
system app = 0
creates session = 0
inetd-compatible = 0
inetd listener = 0
abandon process group = 0
one-shot = 0
event monitor = 0
penalty box = 0
pended non-demand spawn = 0
role account = 0
launch only once = 0
system support = 0
app-like = 0
inferred program = 0
joins gui session = 0
joins host session = 0
parameterized sandbox = 0
resolve program = 0
abandon coalition = 0
high bits aslr = 0
extension = 0
nano allocator = 0
no initgroups = 0
start on fs mount = 0
endpoints initialized = 1
is copy = 0
disallow all lookups = 0
system service = 1
protected by submitter = 0
}
}

谢谢支持

  • 微信二维码: