按给定的xcode/clang检测支持的最低OSX版本
我有两个普通的C程序(实际上是由一些主机编写的按给定的xcode/clang检测支持的最低OSX版本,xcode,macos,makefile,backwards-compatibility,Xcode,Macos,Makefile,Backwards Compatibility,我有两个普通的C程序(实际上是由一些主机编写的dlopen()ed插件)需要编译,我希望支持尽可能多的OSX/macOS版本。 支持的OSX/macOS版本的实际数量并不那么重要,但我努力实现最大覆盖率(“任何可能的”)。 C程序实际上不使用libc之外的任何库,并且是跨平台的(linux/windows/macOS) 为了实现最大的兼容性,在macOS上编译时,我使用-mmacosx version min标志 过去,我使用-mmacosx version min=10.5在macOS Sie
dlopen()
ed插件)需要编译,我希望支持尽可能多的OSX/macOS版本。
支持的OSX/macOS版本的实际数量并不那么重要,但我努力实现最大覆盖率(“任何可能的”)。
C程序实际上不使用libc之外的任何库,并且是跨平台的(linux/windows/macOS)
为了实现最大的兼容性,在macOS上编译时,我使用-mmacosx version min
标志
过去,我使用-mmacosx version min=10.5
在macOS Sierra上构建二进制文件,该版本过去运行良好。此标志现在已在myMakefile
中硬编码
但是,由于我已将构建机器升级到macOS Mojave,构建失败的原因是:
ld:找不到用于-lgcc_.10.5的库
因此,XCode的最新版本似乎有一个最低部署目标OSX-10.6。
显然,我可以去更新我所有的Makefile以使用-mmacosx version min=10.6
,但我想当苹果决定放弃10.6支持时,我很快就会遇到同样的问题
所以我的问题是:是否有任何方法可以通过编程方式确定构建主机上-mmacosx version min
支持的最小值
我的构建系统是一个非常简单的纯GNU make(没有autotools、CMake等),我希望保持这种方式。
因此,任何检查都应该足够简单,可以在make
调用开始时进行
理想的情况是:
CFLAGS+=-mmacosx-version-min=$(shell xcodebuild --minimum-supported-version)
想法
注意:我的目标生成主机是无头CI计算机,通常只安装“cmdline”版本的生成工具。任何建议的解决方案都应该在没有安装完整XCode套件的系统上运行
关于旧系统
有趣的是,在Sierra上指定一个非常低的部署目标处理得更加优雅:
例如,添加-mmacosx version min=10.1
可以毫无问题地编译,创建一个x86_64二进制文件(仅从OSX-10.4开始支持iirc),并且根据,它仅与OSX-10.4兼容
鉴于clang/Xcode/的旧版本。。。优雅地处理-mmacosx version min
的越界值,我想知道这是否是苹果方面的实际回归错误
进一步资料
这是Mojave上的编译器告诉我的关于它自己的版本:
$cc--版本
苹果LLVM版本10.0.1(clang-1001.0.46.4)
目标:x86_64-apple-darwin18.0.0
线程模型:posix
InstalledDir:/Library/Developer/CommandLineTools/usr/bin
在Sierra(一切正常的地方),我得到:
$cc--版本
苹果LLVM 9.0.0版(clang-900.0.38)
目标:x86_64-apple-darwin16.7.0
线程模型:posix
InstalledDir:/Library/Developer/CommandLineTools/usr/bin
让您了解纯make编程和as-helper库的外观:
include gmtt/gmtt.mk
#CC_VERSION_OUTPUT := Apple LLVM version 10.0.1 (clang-1001.0.46.4) \
#Target: x86_64-apple-darwin18.0.0 \
#Thread model: posix \
#InstalledDir: /Library/Developer/CommandLineTools/usr/bin
CC_VERSION_OUTPUT := Apple LLVM version 9.0.0 (clang-900.0.38) \
Target: x86_64-apple-darwin16.7.0 \
Thread model: posix \
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
CC_VERSION := $(call glob-match,$(CC_VERSION_OUTPUT),Apple LLVM version * (clang-*)*Target: *-apple-* *)
LLVM_VERSION := $(subst ., ,$(word 2,$(CC_VERSION)))
LLVM_MAJOR := $(word 1,$(LLVM_VERSION))
LLVM_MINOR := $(word 2,$(LLVM_VERSION))
CLANG_VERSION := $(word 4,$(CC_VERSION))
PLATFORM := $(word 8,$(CC_VERSION))
OS := $(word 10,$(CC_VERSION))
# Table for OSX version minimum (last column)
# platform | OS | LVM-major | LLVM-minor | OSX-version
define COMPATIBILITY_TABLE :=
5
x86_64 darwin16.7.0 9 0 10.5
x86_64 darwin18.0.0 10 0 10.6
endef
#$(info $(LLVM_MAJOR) $(LLVM_MINOR) $(OS) $(PLATFORM))
MACOSX_VERSION_MIN := $(call select,5,$(COMPATIBILITY_TABLE),$$(and $$(call str-eq,$$1,$(PLATFORM)),\
$$(call str-eq,$$2,$(OS)),\
$$(or $$(call int-ge,$$3,$(LLVM_MAJOR)),\
$$(and $$(call int-eq,$$3,$$(LLVM_MAJOR)),\
$$(call int-ge,$$4,$(LLVM_MINOR))))))
$(info -mmacosx_version_min=$(MACOSX_VERSION_MIN))
select语句的where子句显然非常嘈杂。根据您的假设,您也可以使用
$(调用glob match…
这是您的问题,因此我的问题是:是否有任何方法可以通过编程方式确定-mmacox version min的最小支持值,因为您不知道如何确定哪个版本支持哪个版本?还是只有编程方式未知?我只对自动检测-mmacosx-version-min.um支持的最小值的方法感兴趣,很抱歉听起来很难听,但问题是:“我想知道决定哪个版本X与版本Y兼容的规则集”还是“如果不是因为提供的语法笨拙和功能受限,我想将我所知道的规则集编程为程序代码“?我希望我的makefile自动将正确的标志传递给编译器,以生成与最大可能范围的macOS/OSX版本兼容的二进制文件。我不确定我是否能完全解析你的“厚问题”。但是我通常在make
语法方面没有问题,但是目前我不知道应该运行哪些符文来计算macOS/Xcode过去、现在和未来版本的工作标志。也许你想看看哪个版本有表格式数据选择和全局模式的工作版本(正则表达式的弱表兄弟)谢谢你的回答。我不介意where子句的噪音;但是这个解决方案需要我手动收集兼容性矩阵(这样我可以将其硬编码到Makefile中),它解析--version
的输出,这似乎是一个非常脆弱的操作(--version
输出的界面有多稳定?例如,Debian的clang
将用废话填充大多数值-只是告诉大家--version
的输出格式可能会比macos min版本变化更大…)您可以通过额外编程使glob match
模式对垃圾完全免疫。将产生什么样的兼容性矩阵(或者更确切地说是其中的一部分)?哪个工具知道兼容性?嗯,是的…这是一开始的问题(或者至少:这是我一开始试图问的问题)