从Intel版本MacBook Pro 2013迁移到MacBook Pro 2023(Apple M2 Pro)后HomeBrew报错"Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)"

通过 TimeMachineIntel 版本 MacBook Pro 2013 迁移到 MacBook Pro 2023(Apple M2 Pro)HomeBrew 报错,如下:

该报错的原因是 HomeBrew 修改了 Apple ARM 版本的设备上的默认目录,默认目录从 /usr/local 调整到了 /opt/homebrew

由于大量的路径被硬编码到了代码中,结果就导致各种运行、安装异常。

我们能做的就是,重新在 /opt/homebrew目录下安装一遍。

参考链接


macOS Big Sur(11.7.5)编译Android 12.0源码过程总结

Android 11系统映像可直接将 ARM 指令转换成 x86 指令,因此以前很多需要真机测试的情况,现在只需要模拟器就可以进行操作了。

不过,根据官方博客 Run ARM apps on the Android Emulator 尾部的一段注意事项:

Note that the ARM to x86 translation technology enables the execution of intellectual property owned by Arm Limited. It will only be available on Google APIs and Play Store system images, and can only be used for application development and debug purposes on x86 desktop, laptop, customer on-premises servers, and customer-procured cloud-based environments. The technology should not be used in the provision of commercial hosted services.

这段事项说明,自己编译的镜像是没办法用上这个功能的,必须是Google编译好的镜像。

前置条件


  • macOS Big Sur(11.7.5)
  • Homebrew (1.1.9 或更高版本)
  • Xcode (13.2.1或更高版本)
  • Android Studio Electric Eel | 2022.1.1 Patch 2

注意:根据Google官方文档,2021年6月22日之后的Android系统版本不支持在macOS系统上构建,我们只能构建之前的版本,或者之后发布的以前版本的补丁修复。目前测试最高只能编译到Android 12.0,  Android  12.1编译不通过。

继续阅读macOS Big Sur(11.7.5)编译Android 12.0源码过程总结

macOS Big Sur(11.7.5)编译Android 11.0源码过程总结

Android 11系统映像可直接将 ARM 指令转换成 x86 指令,因此以前很多需要真机测试的情况,现在只需要模拟器就可以进行操作了。

不过,根据官方博客 Run ARM apps on the Android Emulator 尾部的一段注意事项:

Note that the ARM to x86 translation technology enables the execution of intellectual property owned by Arm Limited. It will only be available on Google APIs and Play Store system images, and can only be used for application development and debug purposes on x86 desktop, laptop, customer on-premises servers, and customer-procured cloud-based environments. The technology should not be used in the provision of commercial hosted services.

这段事项说明,自己编译的镜像是没办法用上这个功能的,必须是Google编译好的镜像。

前置条件


  • macOS Big Sur(11.7.5)
  • Homebrew (1.1.9 或更高版本)
  • Xcode (13.2.1或更高版本)
  • Android Studio Electric Eel | 2022.1.1 Patch 2

注意:根据Google官方文档,2021年6月22日之后的Android系统版本不支持在macOS系统上构建,我们只能构建之前的版本,或者之后发布的以前版本的补丁修复。目前测试最高只能编译到Android 12.0,  Android  12.1编译不通过。

继续阅读macOS Big Sur(11.7.5)编译Android 11.0源码过程总结

macOS TimeMachine恢复隐藏文件

macOS自带的时间机器(TimeMachine)还是很好用的,只是如果误删的文件是隐藏文件,操作起来稍微复杂了一些。具体参考如下:

  1. Open the Terminal.

  2. Run the following command:

  3. Go to the location of the missing hidden folder and invoke Time Machine to restore it.

  4. Run the following command to hide files:

参考链接


How to access hidden files to restore in Time Machine

macOS Big Sur (11.7.2) 通过Docker Desktop安装MySQL

安装 Docker Desktop

首先去 Docker 官网下载 macOS 版本的 Docker Desktop 版本(目前(2023/01/06)的最新版本是 4.15.0 (93002)),并安装。

安装 MySQL

通过 Docker Desktop 安装MySQL ,整个过程参考如下:

继续阅读macOS Big Sur (11.7.2) 通过Docker Desktop安装MySQL

Ubuntu 22.04搭建TimeMachine

  • 创建一个目录,作为 TimeMachine 保存数据的目录。

  • 安装 netatalk 服务和 avahi-daemon 服务。

  • 编辑 netatalk 的配置文件:

  • 在该文件原来的基础上,或新增以下配置:

  • 重启服务。

现在,你在 TimeMachine 上应该可以看到这个备份服务了,选择该备份服务就可以开始你的第一次备份了。

注意: Debian 12.5 系统上不能安装 netatalk ,原因是这个项目已经长时间没人维护了,后续建议直接使用 SMB 建立 TimeMachine 的备份服务器。

参考链接


VirtualBox 7.0.4安装macOS Monterey 12.6.1

硬件要求

Intel E3-1230 v3 可以成功安装, AMD Ryzen 5900 CPU 在 Linux 系统上,需要配置 CPU 模仿 Intel CPU 的特性。并且 CPU 部分,不要启用 嵌套VT-x/AMD-V

生成系统安装镜像

macOS (实验使用的系统是 macOS Big Sur (11.7.1))系统上,执行如下命令,生成系统安装镜像

继续阅读VirtualBox 7.0.4安装macOS Monterey 12.6.1

API Availability and Target Conditionals

Writing code for multiple Apple platforms can be tricky, this post aims to provide some guidance and explanations for ways to write code that works on different Apple platforms (iOS, macOS, watchOS, tvOS) and different versions of SDKs, and the OSes at runtime.

Target conditionals

First, let’s take a look at how to tell apart the OS you are compiling for at build time, using the preprocessor (in case of Objective-C) or compilation conditions (Swift).

Swift

In Swift checking the OS you are building for at comile time is done using compilation conditionals and specific platform condition functions:

The os() function can be used to check for the OS the code is compiled for, it takes one argument, which is the operating system name (not quoted). Possible operating system names at the time of writing are macOSiOStvOSwatchOS and Linux.

For example:

Of course sometimes you need to check if you are running the simualtor or not, to do that there is the targetEnvironment() function. It takes one argument, which is the target environment name (not quoted). Possible values are simulator and macCatalyst (since Swift 5.1).

Objective-C, C and C++

For Objective-C, C and C++ conditional compilation is handled by the preprocessor. Apple provides the TargetConditionals.h header which contains specific defines for this.

This header has a lot of defines, I will only list the most useful ones here:

TARGET_OS_OSX
Compiling for macOS
TARGET_OS_IOS
Compiling for iOS
TARGET_OS_TV
Compiling for tvOS
TARGET_OS_WATCH
Compiling for watchOS
TARGET_OS_MACCATALYST
Compiling for Catalyst
TARGET_OS_SIMULATOR
Compiling for Simulator

For example:

To check if compiling for the simulator, just use the TARGET_OS_SIMULATOR define:

Note that there is a TARGET_OS_MAC define, while this sounds like it will be true only for macOS, it is actually true for all Darwin OSes including iOS and tvOS. Another define which can be confusing is the TARGET_OS_IPHONE, which is actually true for all “mobile” platforms, so iOS, tvOS, watchOS and Catalyst.

Clang-specific preprocessor extensions

Since Clang 6.0 or Xcode 9.3 (r320734) Clang has preprocessor extensions similar to the Swift condition functions which can be used to achieve the same as with the target conditional defines above.

To check the OS code is compiled for, there is the __is_target_os() preprocessor macro, which takes a single argument, the operating system name. Possible values for Apple OSes are macOSiOStvOSwatchOS.

For example:

To check what environement the code is compiled for, similar to Swift there is the __is_target_environment() preprocessor macro, which takes as argument the environment name. Possible values are simulator and macabi (Catalyst).

API availability

Something that usually is closely related to above discussed conditional compilation is the need to handle API availability gracefully. There are various aspects to consider about API availability, one is API availability at runtime, another is API availability at compile time depending on the used SDK version.

What is API availability?

API availability, as the name suggests, means if a specific API (function, class, method, etc.) is actually available.

macOS, iOS, tvOS and watchOS handle API availability in the same way, when a new API is introduced it is annotate with a specific macro that indicates the availability of that API. The macro expands to annotations for the API that indicate how the linker is expected to handle linking to it and can provide additional warnings or errors during compilation when using a deprecated API or trying to use a “too new” API in an application set to run on older appleOS versions that lack this API.

This sounds all very abstract and complex, so let’s have a look at this using an example, the clock_gettime() function. If we look at the manpage for clock_gettime we can see that it was introduced in macOS 10.12:

So let’s have a look at how the header declares this function:

So these functions are annotate with __CLOCK_AVAILABILITY, which expands to:

So to be more precise than what the man page tells us, this API is available since macOS 10.12, iOS 10.0, tvOS 10.0 and watchOS 3.0, great!

Of course that still doesn’t provide the full story, to understand what exactly the availability macros do, let’s have a look at the header defining those, Availability.h. Checking this header, we can see that these macros actually expand to (indirectly using a other macros) use of the availability attribute. I recommend reading this for all the details about how exactly this works. The most important takeaway for the purpose of this article is the following:

A declaration can typically be used even when deploying back to a platform version prior to when the declaration was introduced. When this happens, the declaration is weakly linked, as if the weak_import attribute were added to the declaration. A weakly-linked declaration may or may not be present a run-time, and a program can determine whether the declaration is present by checking whether the address of that declaration is non-NULL.

Note that in addition to the Availability.h header, there is the AvailabilityMacros.h header which works similar to the Availability.h header. Depending on the Framework, it might use either the Availability.h or the older AvailabilityMacros.h header.

Checking API availability at runtime

Now let’s see how we can use such a “partially” avaialble function:

If we now compile this targeting macOS 10.14 like that, it just works as expected:

But if we were to try to compile targeting macOS 10.10, we would get a warning:

The -Wunguarded-availability flag is what causes the compiler to emit this warning. For APIs available since macOS 10.13, iOS 11, watchOS 4 and tvOS 11 you will get these warnings even without specifying this flag, as there is a new flag-Wunguarded-availability-new which is enabled by default in recent Clang/Xcode versions.

As the name of the warning already gives it away, it only warns about “unguarded” availability, which implies we can “guard” such API usage. There are two ways how this can be done.

Checking the symbols address

The “old” way to check if a partially available function is available would be to check its address:

Not only is this a bit weird to read, it has some downsides:

  • The compiler will still warn about this
  • Objective-C methods and classes can’t easily be checked this way
  • It is cumbersome to check all relevant symbols this way
Using the availability helper

Fortunately since some time there is a bette way to handle this! In fact, the compiler would already points this out in the partial availability warning:

note: enclose 'clock_gettime' in a __builtin_available check to silence this warning

So let’s do that:

And now it will compile without warning again! On macOS at least, that is. We can check multiple platform versions just by listing them all:

The star at the end is mandatory and means “all other platforms”. So the previous check that just listed macOS would still compile for iOS and crash at runtime when ran on iOS versions lower than iOS 10 which lack clock_gettime. So take care to cover all cases where the code will run in your availability check!

In Objective-C there is the @available helper which looks a bit nicer than the longer version from C but is used in the exact same way:

In Swift there is #available, again the usage is the same except for the different name:

Note that negating the check or using it together with any other condition is not supported and does not properly guards availability!

Additionally keep in mind that this is a runtime check, so using APIs inside a availability check that are missing in the current SDK version that is compiled with is still an error. To support multiple SDK versions, see the next section for how to check at compile-time!

Checking API availability at compile-time

Sometimes it is necessary to check the availability of a specific API at compile-time, for example when you want to remain compatible with multiple Apple SDKs, where some versions offer new API that you want to use and some versions lack this API.

In the previous section I already mentioned two headers, Availability.h and AvailabilityMacros.h. These headers define two important macros:

__<OS-VARIANT>_VERSION_MAX_ALLOWED
Indicates the maximum version that we are allowed to use APIs from.
__<OS-VARIANT>_VERSION_MIN_REQUIRED
Indicates the minimum required version that we are allowed to use APIs from.

The <OS-VARIANT> needs to be replaced with the OS variant we want to check for and can be MAC_OS_XIPHONE_OSTV_OS or WATCH_OS.

The above sounds quite abstract so lets illustrate it with a example. Suppose we have a new API introduced for macOS 10.12, so it is first present in the macOS 10.12 SDK. If we were to compile with that SDK, the __MAC_OS_X_VERSION_MAX_ALLOWED macro is automatically set to the version of the SDK, as that is the maximum macOS version that we can use APIs from, we cannot ever use any APIs newer than the SDK we are using because those are simply not declared. So in case of the 10.12 SDK, __MAC_OS_X_VERSION_MAX_ALLOWED will be 101200.

If we want to stay compatible with older SDKs, we can use the following preprocessor macros:

Note that there are defines for the specific appleOS versions in the availability headers, like __MAC_10_12 so it is tempting to write __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_12 but this will not work because lower SDK versions, like for example the macOS 10.11 SDK will not have the define for higher macOS versions like macOS 10.12!

What is important to note is that the preprocessor checks are done at compile-time, so proper availability handling at runtime is still needed, see the previous section for details about that!

The second macro, __<OS-VARIANT>_VERSION_MIN_REQUIRED, is useful when you have legacy code that you want to disable when targeting recent enough appleOS versions. Suppose we have function needed for macOS <= 10.11, we can easily disable that when targeting macOS 10.12 or higher by using the __MAC_OS_X_VERSION_MIN_REQUIRED macro:

Of course a lot of other and more complex scenarios are possible with more complex checks, but I won’t cover all of the possibilities here.

Note that the AvailabilityMacros.h header defines MAC_OS_X_VERSION_MIN_REQUIRED without the two leading underscores, but the Availability.h header does not define those. Both define the version with the leading underscores so to prevent confusing code I would recommend to not use the version without the leading underscores.

Note that the above only works for C/C++/Objective-C code, in Swift there is currently no way to check the SDK at compile-time.

参考链接


VirtualBox 7.0.4安装macOS High Sierra

硬件要求

Intel E3-1230 v3 可以成功安装, AMD Ryzen 5900 CPULinux 系统上,需要配置 CPU 模仿 Intel CPU 的特性。并且 CPU 部分,不要启用 嵌套VT-x/AMD-V

生成系统安装镜像

macOS (实验使用的系统是 macOS Big Sur (11.7.1))系统上,执行如下命令,生成系统安装镜像

继续阅读VirtualBox 7.0.4安装macOS High Sierra

macOS Big Sur(11.6.7/Intel CPU)编译Android/iOS/macOS版本的RocksDB 6.29.5

RocksDB 7.0 开始,RocksDB 要求编译的 C++ 必须支持 C++ 17 ,( Dropping some compiler support in 7.0#9388)但是目前的Android/iOS版本显然暂时还不能大范围的适配 C++ 17,因此我们目前只能使用 6.x 版本。

Android:

iOS/macOS ARM:

macOS x86:

参考链接