ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库
1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库
- 1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库
- 1.1. 安装依赖
- 1.2. 安装 osxcross 及 macOS SDK
- 1.2.1. 可能错误
- 1.3. 编译 cmake 类工程
- 1.4. 编译 configure 类工程
- 1.5. 单文件编译及其他环境编译
- 1.6. 打包成 docker 镜像
- 1.7. 使用 docker 编译 cmake 工程
你可以使用osxcross工具来搭建适用于 macOS 的交叉编译环境,下边以 ubuntu22.04 为例,演示如何搭建 macOS 交叉编译环境。
1.1. 安装依赖
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下载
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
设置环境变量,以便在终端中使用交叉编译工具:
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
- 你得有一台可用的 macOS 设备
- 在 macOS 系统上克隆 osxcross 仓库
- 将 Mac SDK 重新打包
git clone https://github.com/tpoechtrager/osxcross.git
cd osxcrosswget -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 指定即可
# 设置系统名称
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)
编译时指定工具链文件:
# 编译时通过 CMAKE_TOOLCHAIN_FILE 指定工具链文件即可
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-mac.cmake ..
1.4. 编译 configure 类工程
#!/bin/sh
# set -x
CUR_DIR=$(cd "$(dirname "$0")"; pwd)
wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gzsrc_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[@]}"; dorm ${dst_dir} -rfif [ ! -d ${dst_dir} ] ;then tar xvf ${src_pkg} ficd ${dst_dir}# 配置交叉编译环境export PATH=$PATH:/data/code/osxcross/target/binexport CC=${platform}-apple-darwin20.4-clangexport 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# 编译和安装makemake installcd -
doneecho "libsodium 1.0.18 编译和安装完成。"
1.5. 单文件编译及其他环境编译
#include <stdio.h>void hello() {printf("Hello from the library!\n");
}
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
其它工程编译
# 配置交叉编译环境, 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查看镜像是否生成成功
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 脚本内容参考如下
# 修改 MOUNT_DIR、OSXCROSS_PATH 这2个宏,可以使用本地的 mac sdk 环境编译
MOUNT_DIR="/my_project"
OSXCROSS_PATH=/osxcross
MAC_TOOLCHAIN=${MOUNT_DIR}/toolchain-mac.cmakeBUILD_DIR=${MOUNT_DIR}/build
DST_DIR=${MOUNT_DIR}/outputbuild_mac() {SYSTEM_PROCESSOR=$1echo "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} ..makemv ${BUILD_DIR}/lib/libFFMPEG.a ${DST_DIR}/${SYSTEM_PROCESSOR}/libFFMPEG.amv ${BUILD_DIR}/lib/libFFMPEG.dylib ${DST_DIR}/${SYSTEM_PROCESSOR}/libFFMPEG.dylibecho "build for ${SYSTEM_PROCESSOR} success"echo "----------------------------------------"
}build_mac aarch64
build_mac x86_64# 创建 universal 通用库
lipo -create ${DST_DIR}/aarch64/libFFMPEG.a ${DST_DIR}/x86_64/libFFMPEG.a -output ${DST_DIR}/libFFMPEG.a
lipo -create ${DST_DIR}/aarch64/libFFMPEG.dylib ${DST_DIR}/x86_64/libFFMPEG.dylib -output ${DST_DIR}/libFFMPEG.dylib
# 验证通用库
lipo -info ${DST_DIR}/libFFMPEG.a
lipo -info ${DST_DIR}/libFFMPEG.dylibrm -rf ${DST_DIR}/aarch64
rm -rf ${DST_DIR}/x86_64chmod 777 ${DST_DIR} -Rrm -rf ${BUILD_DIR}
- 上边的脚本用到了本地的
toolchain-mac.cmake文件,内容如下, 位置可以随便放,在 build.sh 中设置即可 - 这个文件没有放在 docker 镜像中,而是在宿主机上,这样可以直接修改,不用重新构建 docker 镜像,也可以直接使用本地的 osxcross 环境
# 设置系统名称
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 等编译工具即可
相关文章:
ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库
1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库 1. ubuntu 交叉编译 macOS 库, 使用 osxcross 搭建 docker 编译 OS X 库 1.1. 安装依赖1.2. 安装 osxcross 及 macOS SDK 1.2.1. 可能错误 1.3. 编译 cmake 类工程1.4. 编译 configure 类工程1.5. 单文件…...
JavaScript 中的单例模式
单例模式在 JavaScript 中是一种确保类只有一个实例,并提供全局访问点的方式。由于 JavaScript 的语言特性(如对象字面量、模块系统等),实现单例有多种方式。 常见实现方式 1. 对象字面量(最简单的单例) …...
深度学习基石:神经网络核心知识全解析(一)
神经网络核心知识全解析 一、神经网络概述 神经网络作为机器学习领域的关键算法,在现代生活中发挥着重要作用,广泛应用于图像识别、语音处理、智能推荐等诸多领域,深刻影响着人们的日常生活。它通过模拟人类大脑神经系统的结构和功能&#…...
java的反编译命令
1. javap -c: 显示方法中的字节码 2. javap -p: 显示所有访问级别,包括private 3. Javap -v: verbose模式,全信息,输出的内容包括: 类的访问标志(access_flags) 类名、父类、接口 …...
影刀填写输入框(web) 时出错: Can not convert Array to String
环境: 影刀5.26.24 Win10专业版 问题描述: [错误来源]行12: 填写输入框(web) 执行 填写输入框(web) 时出错: Can not convert Array to String. 解决方案: 1. 检查变量内容 在填写输入框之前,打印BT和NR变量的值ÿ…...
词语关系图谱模型
参数配置说明 sentences, # 分词后的语料(列表嵌套列表) vector_size100, # 每个词的向量维度 window5, # 词与上下文之间的最大距离(滑动窗口大小) min_count5, # 忽略出现次数小于5的…...
《C++ 模板:泛型编程的核心》
C模板详解 模板是C中实现泛型编程的重要特性,它允许你编写与数据类型无关的代码。模板可以分为函数模板和类模板两种。 1. 函数模板 函数模板允许你定义一个可以处理多种数据类型的函数。 基本语法 template <typename T> T functionName(T parameter1, T…...
HTTP的请求消息Request和响应消息Response
一:介绍 (1)定义 service方法里的两个参数 (2)过程 Request:获取请求数据 浏览器发送http请求数据(字符串),字符串被tomcat解析,解析后tomcat会将请求数据放入request对象 Response:…...
解决Python与Java交互乱码问题:从编码角度优化数据流
在现代软件开发中,跨语言系统的集成已经成为日常工作的一部分。特别是当Python和Java之间进行交互时,编码问题往往会成为导致数据传输错误、乱码以及难以调试的主要原因之一。 你是否曾遇到过这种情境:Python脚本通过标准输出返回了正确的数…...
DES、3DES、SM4 加密算法简介
1. DES(Data Encryption Standard) 设计时间:1975 年(IBM 开发,1977 年被 NIST 采纳为美国联邦标准)。 密钥长度:64 位(实际有效 56 位 8 位校验)。 分组长度…...
C++异步操作 - future async package_task promise
异步 异步编程是一种程序设计范式,允许任务在等待耗时操作(如I/O、网络请求)时暂停执行,转而处理其他任务,待操作完成后自动恢复。其核心目标是避免阻塞主线程,提升程序的并发性和响应速度…...
Feign 深度解析:Java 声明式 HTTP 客户端的终极指南
Feign 深度解析:Java 声明式 HTTP 客户端的终极指南 Feign 是由 Netflix 开源的 声明式 HTTP 客户端,后成为 Spring Cloud 生态的核心组件(现由 OpenFeign 维护)。它通过注解和接口定义简化了服务间 RESTful 通信,并…...
08前端项目----升序/降序
升序/降序 vue实现升序/降序服务器处理 vue实现升序/降序 用vue实现升序/降序,以及css绘制三角形 <div class"sui-navbar"><div class"navbar-inner filter"><ul class"sui-nav"><li class"active"&g…...
用Java实现简易区块链:从零开始的探索
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 区块链技术作为近年来的热门话题&am…...
JavaScript 渲染内容爬取实践:Puppeteer 进阶技巧
进一步探讨如何使用 Puppeteer 进行动态网页爬取,特别是如何等待页面元素加载完成、处理无限滚动加载、单页应用的路由变化以及监听接口等常见场景。 一、等待页面元素加载完成 在爬取动态网页时,确保页面元素完全加载是获取完整数据的关键。Puppeteer…...
数据结构——栈以及相应的操作
栈(Stack) 在维基百科中是这样定义的: 堆栈(stack) 又称为栈或堆叠,是计算机科学中的一种抽象资料类型,只允许在有序的线性资料集合中的一端(称为堆栈顶端,top)进行加入数据(push)和…...
SVG 与 VSCode:高效设计与开发的完美结合
SVG 与 VSCode:高效设计与开发的完美结合 引言 随着互联网技术的飞速发展,网页设计已经成为了一个重要的领域。SVG(可缩放矢量图形)作为一种矢量图形格式,因其独特的优势,在网页设计中得到了广泛应用。而VSCode(Visual Studio Code)作为一款功能强大的代码编辑器,同…...
如何应对政策变化导致的项目风险
应对政策变化导致的项目风险,核心在于:加强政策研判机制、建立动态应对流程、构建合规应急预案、强化跨部门联动、提升项目柔性与调整能力。其中,加强政策研判机制 是所有防范工作中的“前哨哨兵”,可以让项目团队在政策风向转变之…...
ASP.Net Web Api如何更改URL
1.找到appsettings.json 修改如下: 主要为urls的修改填本机私有地址即可 {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": &q…...
在 Vue 3 中将拆分后的数组合并回原数组
接上文Vue 3 中按照某个字段将数组分成多个数组_vue3怎么进行数组对象--分割对象-CSDN博客 方法一:使用 flat() 方法 // 假设这是拆分后的多维数组 const splitArrays [[{id: 1, category: A}, {id: 3, category: A}],[{id: 2, category: B}, {id: 5, category: …...
【HTTPS协议原理】数据加密、如何防止中间人攻击、证书和签名、HTTPS完整工作流程
⭐️个人主页:小羊 ⭐️所属专栏:Linux网络 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 数据加密常见的加密方式数据摘要方案一:仅使用对称加密方案二:仅使用非对称加密方案三:双…...
Java中链表的深入了解及实现
一、链表 1.链表的概念 1.1链表是⼀种物理存储结构上⾮连续存储结构,数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的 实际中链表的结构⾮常多样,以下情况组合起来就有8种链表结构: 2.链表的实现 1.⽆头单向⾮循环链表实现 链表中的…...
【武汉理工大学第四届ACM校赛】copy
copy 题目描述代码代码解释: 链接:https://ac.nowcoder.com/acm/contest/108683/E 题目描述 小s苦于在不同的窗口之间复制粘贴, 于是他突发奇想,把所有要复制的内容都复制到了一个剪贴板中,但他突然发现由于他复制的…...
植物大战僵尸杂交版v3.6最新版本(附下载链接)
B站游戏作者潜艇伟伟迷于4月19日更新了植物大战僵尸杂交版3.6版本!!!,有b站账户的记得要给作者三连关注一下呀! 不多废话下载链接放上: 夸克网盘链接::https://pan.quark.cn/s/1af9b…...
【Ansible】批量管理 Windows自动化运维
一,前期准备 1,控制端(Linux)的要求 Ansible可以在安装了Python 2(2.7版)或Python 3(3.5及更高版本)的任何机器上运行。控制端计算机不支持Windows。 2,客户端&#x…...
【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读
👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 👍 欢迎点赞、收藏、关注,跟上我的更新节奏 📚欢迎订阅专栏…...
背包问题模板
文章目录 01背包题意思路代码优化 完全背包题意思路代码优化 多重背包题意思路代码优化 分组背包题意思路代码 01背包 特点:每件物品最多只能用一次 01背包问题 题意 给出每件物品的体积v,价值w,求解能装入背包的的物品的最大价值,并且每件物品只能选一…...
Redis 处理读请求
在前文“Redis 接收连接”中,Redis 将接收的客户端连接加入了 epoll 中监听,同时还设置了读事件处理器 connSocketEventHandler。 假设现在客户端向 Redis 发来一条 set key value 命令。 事件循环 aeProcessEvents 在事件循环 aeProcessEvents 中会调…...
Sentinel源码—8.限流算法和设计模式总结二
大纲 1.关于限流的概述 2.高并发下的四大限流算法原理及实现 3.Sentinel使用的设计模式总结 3.Sentinel使用的设计模式总结 (1)责任链模式 (2)监听器模式 (3)适配器模式 (4)模版方法模式 (5)策略模式 (6)观察者模式 (1)责任链模式 一.责任链接口ProcessorSlot 二.责…...
VulnHub-DarkHole_1靶机渗透教程
VulnHub-DarkHole_1靶机渗透教程 1.靶机部署 [Onepanda] Mik1ysomething 靶机下载:https://download.vulnhub.com/darkhole/DarkHole.zip 直接使用VMware打开就行 导入成功,打开虚拟机,到此虚拟机部署完成! 注意:…...
