osxcross 搭建 macOS 交叉编译环境

1. osxcross 搭建 macOS 交叉编译环境

  • [1. osxcross 搭建 macOS 交叉编译环境](#1. osxcross 搭建 macOS 交叉编译环境)
    • [1.1. 安装依赖](#1.1. 安装依赖)
    • [1.2. 安装 osxcross 及 macOS SDK](#1.2. 安装 osxcross 及 macOS SDK)
      • [1.2.1. 可能错误](#1.2.1. 可能错误)
    • [1.3. 编译 cmake 类工程](#1.3. 编译 cmake 类工程)
    • [1.4. 编译 configure 类工程](#1.4. 编译 configure 类工程)
    • [1.5. 单文件编译及其他环境编译](#1.5. 单文件编译及其他环境编译)
    • [1.6. 打包成 docker 镜像](#1.6. 打包成 docker 镜像)
    • [1.7. 使用 docker 编译 cmake 工程](#1.7. 使用 docker 编译 cmake 工程)

你可以使用osxcross工具来搭建适用于 macOS 的交叉编译环境,下边以 ubuntu22.04 为例,演示如何搭建 macOS 交叉编译环境。

1.1. 安装依赖

shell 复制代码
sudo apt-get update
sudo apt-get install -y clang llvm-dev libxml2-dev uuid-dev libssl-dev make cmake zlib1g-dev xz-utils git wget

1.2. 安装 osxcross 及 macOS SDK

具体 macOS SDK版本取决于你的需求,你可以从MacOSX-SDKs下载

shell 复制代码
git clone https://github.com/tpoechtrager/osxcross.git
cd osxcross

# 下载Mac OS X SDK
wget -nc https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz
mv MacOSX11.3.sdk.tar.xz tarballs/

# UNATTENDED 表示是否静默安装
# OSX_VERSION_MIN 表示最低支持的 macOS 版本
# SDK_VERSION 表示 macOS SDK 版本, 可以不指定默认从 tarballs 目录中选择
# 编译结束后,会在 target 目录下生成交叉编译工具,target/bin 目录下包含 clang 和 clang++ 等交叉编译工具
SDK_VERSION=11.3 UNATTENDED=yes OSX_VERSION_MIN=10.7 ./build.sh

设置环境变量,以便在终端中使用交叉编译工具:

shell 复制代码
export PATH=$PATH:/data/code/osxcross/target/bin/

1.2.1. 可能错误

  • 使用 MacOS11.0 的时候出现报错,Given SDK does not contain libc++ headers (-stdlib=libc++ test may fail)

    • 表明你所使用的 Mac OS X SDK 里缺少 libc++ 头文件,使用 tools/gen_sdk_package.sh 脚本在 macOS 系统上重新打包 SDK
    1. 你得有一台可用的 macOS 设备
    2. 在 macOS 系统上克隆 osxcross 仓库
    3. 将 Mac SDK 重新打包
shell 复制代码
git clone https://github.com/tpoechtrager/osxcross.git
cd osxcross

wget -nc https://github.com/phracker/MacOSX-SDKs/releases/download/11.0-11.1/MacOSX11.0.sdk.tar.xz
tar -xf MacOSX11.0.sdk.tar.xz

# 重新打包SDK,这样就会包含 libc++ 头文件了
./tools/gen_sdk_package.sh MacOSX11.0.sdk

1.3. 编译 cmake 类工程

  • 注意修改 osxcross 所在目录,下边举例是 /data/code/osxcross
  • 注意 bin 文件的前缀,不同的 MacOS 版本有不同的前缀,比如我的 MacOS11.3 的前缀是 x86_64-apple-darwin20.4
  • 将下边内容写入 toolchain-mac.cmake 文件,编译时通过 CMAKE_TOOLCHAIN_FILE 指定即可
shell 复制代码
# 设置系统名称
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

# 设置交叉编译工具链的路径,注意修改 osxcross 路径,注意工具链前缀
set(TOOLCHAIN_PREFIX /data/code/osxcross/target/bin/x86_64-apple-darwin20.4)

# 替换为你实际的 osxcross 安装路径
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++)

# 设置搜索路径,注意修改 osxcross 路径
set(CMAKE_FIND_ROOT_PATH /data/code/osxcross/target/macports/pkgs/opt/local)

# 只在交叉编译环境中搜索库和头文件
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

编译时指定工具链文件:

shell 复制代码
# 编译时通过 CMAKE_TOOLCHAIN_FILE 指定工具链文件即可
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-mac.cmake ..

1.4. 编译 configure 类工程

shell 复制代码
#!/bin/sh
# set -x
CUR_DIR=$(cd "$(dirname "$0")"; pwd)
wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz

src_pkg=libsodium-1.0.18.tar.gz
dst_dir=libsodium-1.0.18
install_dir=${PWD}/target/

# 删除后,重新解压编译,避免之前的版本对当前版本有影响
rm -rf ${install_dir}/*

platforms=("x86_64" "aarch64")
for platform in "${platforms[@]}"; do
	rm ${dst_dir} -rf
	if [ ! -d ${dst_dir} ] ;then	
		tar xvf ${src_pkg} 
	fi
	cd ${dst_dir}

	# 配置交叉编译环境
	export PATH=$PATH:/data/code/osxcross/target/bin
	export CC=${platform}-apple-darwin20.4-clang
	export CXX=${platform}-apple-darwin20.4-clang++

	# 配置 libsodium 编译选项
	./configure --host=${platform}-apple-darwin20.4 \
				--prefix=${install_dir}/${platform} \
				--with-sysroot=/data/code/osxcross/target/macports/pkgs/opt/local
	# 编译和安装
	make
	make install
	cd -
done

echo "libsodium 1.0.18 编译和安装完成。"

1.5. 单文件编译及其他环境编译

c 复制代码
#include <stdio.h>

void hello() {
    printf("Hello from the library!\n");
}
shell 复制代码
export PATH=$PATH:/data/code/osxcross/target/bin/

# 编译成目标文件
o64-clang -c example.c -o example.o
# 生成静态库
ar rcs libexample.a example.o
# 生成动态库
o64-clang -shared example.c -o libexample.dylib

其它工程编译

shell 复制代码
# 配置交叉编译环境, platform 可以是 x86_64 或 aarch64 等
export PATH=$PATH:/data/code/osxcross/target/bin
export CC=${platform}-apple-darwin20.4-clang
export CXX=${platform}-apple-darwin20.4-clang++

1.6. 打包成 docker 镜像

  • 为了简单,可以使用 Dockerfile 来搭建交叉编译环境,这样可以避免在宿主机上安装依赖
  • 将下边内容保存为 Dockerfile 文件,然后执行 docker build -t mac_build . 生成镜像,docker images 查看镜像是否生成成功
shell 复制代码
FROM ubuntu:22.04

# 避免在安装过程中出现交互式提示
ENV DEBIAN_FRONTEND=noninteractive

# 安装必要的依赖
RUN apt-get update && \
    apt-get install -y \
    clang \
    llvm-dev \
    libxml2-dev \
    uuid-dev \
    libssl-dev \
    make \
    cmake \
    zlib1g-dev \
    xz-utils \
    git \
    wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# 克隆 osxcross 仓库
RUN git clone https://github.com/tpoechtrager/osxcross.git /osxcross
WORKDIR /osxcross

# 下载 Mac OS X SDK
RUN wget -nc https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz && \
    mv MacOSX11.3.sdk.tar.xz tarballs/

# 编译 osxcross
ENV SDK_VERSION=11.3
ENV UNATTENDED=yes
ENV OSX_VERSION_MIN=10.7
RUN ./build.sh

# 设置环境变量
ENV PATH=$PATH:/osxcross/target/bin/
  • 可以给 image 打 tag docker tag mac_build:latest xx.cloud.com.cn/mac_build:1.0
  • 也可以上传镜像 docker push xx.cloud.com.cn/mac_build:1.0 当然如果只是本地使用,可以不上传

1.7. 使用 docker 编译 cmake 工程

  • 编译本地 cmake 管理的工程
    • 假设本地工程目录是 /home/xxx/my_project
    • 执行 docker run -it -v /home/xxx/my_project:/my_project mac_build:1.0 build.sh 即可
    • build.sh 脚本内容参考如下
shell 复制代码
# 修改 MOUNT_DIR、OSXCROSS_PATH 这2个宏,可以使用本地的 mac sdk 环境编译
MOUNT_DIR="/my_project"
OSXCROSS_PATH=/osxcross
MAC_TOOLCHAIN=${MOUNT_DIR}/toolchain-mac.cmake

BUILD_DIR=${MOUNT_DIR}/build
DST_DIR=${MOUNT_DIR}/output

build_mac() {
    SYSTEM_PROCESSOR=$1
    echo "start build for ${SYSTEM_PROCESSOR}..."
    mkdir -p ${DST_DIR}/${SYSTEM_PROCESSOR}
    rm -rf ${BUILD_DIR}
    mkdir -p ${BUILD_DIR}
    cd ${BUILD_DIR}

    cmake -DSYSTEM_PROCESSOR=${SYSTEM_PROCESSOR} -DOSXCROSS_PATH=${OSXCROSS_PATH} -DCMAKE_TOOLCHAIN_FILE=${MAC_TOOLCHAIN} ..
    make

    mv ${BUILD_DIR}/lib/libFFMPEG.a ${DST_DIR}/${SYSTEM_PROCESSOR}/libFFMPEG.a
    mv ${BUILD_DIR}/lib/libFFMPEG.dylib ${DST_DIR}/${SYSTEM_PROCESSOR}/libFFMPEG.dylib

    echo "build for ${SYSTEM_PROCESSOR} success"
    echo "----------------------------------------"
}

build_mac aarch64
build_mac x86_64
  • 上边的脚本用到了本地的 toolchain-mac.cmake 文件,内容如下, 位置可以随便放,在 build.sh 中设置即可
  • 这个文件没有放在 docker 镜像中,而是在宿主机上,这样可以直接修改,不用重新构建 docker 镜像,也可以直接使用本地的 osxcross 环境
shell 复制代码
# 设置系统名称
set(CMAKE_SYSTEM_NAME Darwin)

if((NOT ${SYSTEM_PROCESSOR} STREQUAL "x86_64") AND (NOT ${SYSTEM_PROCESSOR} STREQUAL "aarch64"))
    message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_PROCESSOR}")
    return()
endif()
set(CMAKE_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR})

message(STATUS "macOS toolchain: CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}, CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}, OSXCROSS_PATH: ${OSXCROSS_PATH}")

# 设置交叉编译工具链的路径
set(TOOLCHAIN_PREFIX ${OSXCROSS_PATH}/target/bin/${CMAKE_SYSTEM_PROCESSOR}-apple-darwin20.4)

# 替换为你实际的 osxcross 安装路径
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++)

# 设置搜索路径
set(CMAKE_FIND_ROOT_PATH ${OSXCROSS_PATH}/target/macports/pkgs/opt/local)

# 只在交叉编译环境中搜索库和头文件
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

其他工程类似,只需要导出对应的 CC/CXX/LD/STRIP 等编译工具即可

相关推荐
2501_916007471 小时前
iOS和macOS应用程序性能分析和优化工具使用综合指南
android·macos·ios·小程序·uni-app·iphone·webview
张小姐的猫21 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
寒水馨1 天前
macOS下载、安装openclaw-v2026.7.1(附安装包OpenClaw-2026.7.1.dmg)
macos·大模型·github·开源软件·ai助手·openclaw·gpt-5.6
白玉cfc1 天前
【iOS】MRC和ARC
macos·ios·cocoa
飞雪金灵1 天前
mac电脑 Maven下载安装和配置环境变量
macos·maven·maven下载安装·mac电脑环境
雨声不在1 天前
macos 12使用docker
macos·docker·容器
一叶龙洲1 天前
ubuntu26.04 xfce美化成mac
服务器·ubuntu·macos
李小白杂货铺2 天前
Oh My Zsh 简记
macos·macbook·zsh·主题·插件·oh my zsh·omz
fukai77222 天前
macOS防止休眠的菜单栏小工具
macos
web守墓人2 天前
【go语言】gotar:使用go语言复刻tar命令,并加入7z支持,可独立运行在windows、linux、macos上
linux·macos·golang