Page MenuHomeFreeBSD

D51087.diff
No OneTemporary

D51087.diff

Index: tools/build/cross-build-macos.sh
===================================================================
--- /dev/null
+++ tools/build/cross-build-macos.sh
@@ -0,0 +1,357 @@
+#!/bin/sh
+# Copyright (c) Mar 2025 Wolfram Schneider <wosch@FreeBSD.org>
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# cross-build-macos.sh - build FreeBSD/arm64 from source on macOS
+# for macOS 14.x and later. Supported FreeBSD branches are
+# stable/15 or later and main.
+#
+# Note: you need to install a new compiler and linker
+# with Homebrew first:
+# brew install llvm lld
+#
+# or with a specific clang version as LLVM20:
+# brew install llvm@20 lld@20
+#
+# Homebrew will install the Command Line Tools for Xcode as well.
+# If not, you can install them with: xcode-select --install
+#
+# get the FreeBSD source:
+# git clone https://codeberg.org/freebsd/freebsd-src
+# cd freebsd-src && ./tools/build/cross-build-macos.sh
+#
+# DEV examples:
+# fresh build (obj cleanup), without OPENSSL compiled, on 9 CPUs,
+# make in silend mode, for the targets buildworld + buildkernel + packages + ftp tarballs
+#
+# env ncpu=9 build_clean=YES build_targets_opt="-s MK_OPENSSL=no" debug=1 TAR_XZ_CMD=tar PKG_FORMAT=tgz \
+# build_targets="buildworld; buildkernel;packages;-C./release obj;-C./release ftp" ./tools/build/cross-build-macos.sh
+#
+
+set -e
+
+: ${debug:="1"}
+
+# homebrew LLVM version, e.g. for version 19: "@19"
+: ${homebrew_llvm_version="@20"}
+
+if [ "$(uname -m)" = "arm64" ]; then
+ # arm64 (Apple M1 ...)
+ : ${homebrew_home="/opt/homebrew"}
+ : ${TARGET:="arm64"}
+ : ${TARGET_ARCH:="aarch64"}
+else
+ # x86_64 (AMD64)
+ : ${homebrew_home="/usr/local"}
+ : ${TARGET:="amd64"}
+ : ${TARGET_ARCH:="amd64"}
+fi
+
+HOMEBREW_PATH="$homebrew_home/opt/llvm${homebrew_llvm_version}/bin:$homebrew_home/opt/lld${homebrew_llvm_version}/bin:$homebrew_home/bin"
+PATH="$HOMEBREW_PATH:/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/sbin:/usr/sbin"; export PATH
+clt_sdk_dir="/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
+
+# the cross build directories as "bmake-build" need a seperate sub-directory for multiple
+# builds on the same machine
+_cwd_string=$(pwd | sed -e 's,/,,' -e 's,/,-,g')
+
+: ${TMPDIR:="/tmp"}
+: ${MAKEOBJDIRPREFIX:="$TMPDIR/freebsd-obj/${_cwd_string}"}; export MAKEOBJDIRPREFIX
+: ${nice_cmd="nice -n10 time"}
+
+# A list of targets to build.
+# If a target requires additional parameters, use a semicolon (";") for spaces
+# e.g. "-C release obj; -C release ftp"
+# or "-C usr.bin/locate"
+#
+
+# everything up to ftp tarballs
+: ${build_targets_release="buildworld;buildkernel;packages;-C./release obj;-C./release ftp"}
+
+if [ "$1" = "full" ]; then
+ build_targets="$build_targets_release"
+ shift
+elif [ "$1" = "buildworld" -o "$1" = "buildkernel" -o "$1" = "packages" ]; then
+ : ${build_targets="$1"}
+ shift
+elif [ "$1" = "release-ftp" ]; then
+ : ${build_targets="-C./release obj;-C./release ftp"}
+ shift
+else
+ : ${build_targets="buildworld;buildkernel"}
+fi
+
+# without clang TOOLCHAIN & debug: NO | YES
+: ${build_fast="YES"}
+
+# other make flags, e.g. "-s" or makefile variable as WITHOUT_MITKRB5=1
+if [ $build_fast = "YES" ]; then
+ : ${build_targets_opt="__MAKE_CONF=/dev/null WITHOUT_TOOLCHAIN=yes WITHOUT_DEBUG_FILES=yes"}
+
+ # due some bugs in bsdtar/xz and share/mk tarball can be really slow
+ : ${TAR_XZ_CMD="tar -Z"}
+ : ${PKG_FORMAT="tgz"}
+ export TAR_XZ_CMD PKG_FORMAT
+else
+ : ${build_targets_opt=""}
+fi
+
+# cleanup objdir for a fresh build (aka `make distclean')
+: ${build_clean="NO"}
+
+# by default show disk usage only for buildworld
+case $build_targets in
+ *buildworld* ) : ${build_show_du="YES"} ;;
+ * ) : ${build_show_du="NO"} ;;
+esac
+
+: ${ncpu:=$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 1)}
+: ${logrotate_max="32"}
+
+if [ "$1" = "help" ]; then
+
+cat <<EOF
+$0 [ help | full | buildworld | buildkernel | packages | release-ftp ]
+
+homebrew_llvm_version="${homebrew_llvm_version}" # LLVM version in homebrew, e.g. "@19" or "@20"
+build_targets="${build_targets}" # make targets to run, separated by semicolon ';'
+build_clean="${build_clean}" # cleanup objdir for a fresh build: "NO" | "YES"
+build_fast="${build_fast}" # without clang TOOLCHAIN & debug: "NO" | "YES"
+build_targets_opt="${build_targets_opt}" # other make flags, e.g.: "-s MK_OPENSSL=no"
+
+debug="${debug}" # 0 | 1
+nice_cmd="${nice_cmd}"
+ncpu="${ncpu}" # empty or number of CPUs to use
+logrotate_max="${logrotate_max}" # number of logfiles 1..N
+
+TARGET="${TARGET}"
+TARGET_ARCH="${TARGET_ARCH}"
+TMPDIR="${TMPDIR}"
+MAKEOBJDIRPREFIX="${MAKEOBJDIRPREFIX}"
+EOF
+
+ exit 0
+fi
+
+if [ ! -e Makefile.inc1 ]; then
+ echo "Makefile.inc1 missing, please run inside a fresh FreeBSD source checkout as /usr/src" >&2
+ exit 1
+fi
+
+if [ -z "$build_targets" ]; then
+ echo "env variable 'build_targets' is empty, nothing to do - give up" >&2
+ exit 1
+fi
+
+for i in clang clang++ clang-cpp ld.lld python3
+do
+ if ! env PATH=$HOMEBREW_PATH /usr/bin/which $i >/dev/null; then
+ echo "missing program: $i for PATH=$HOMEBREW_PATH" >&2
+ exit 1
+ fi
+done
+
+# https://wiki.freebsd.org/ExternalToolchain
+export CPP="clang-cpp"
+export CC="clang"
+export CXX="clang++"
+export XCC="clang"
+
+# due a bug in share/mk the XLD/LD value must be a full path
+#export XLD="ld.lld"
+export XLD="$homebrew_home/opt/lld${homebrew_llvm_version}/bin/ld.lld"
+export XCPP="clang-cpp"
+export XCXX="clang++"
+
+logrotate ()
+{
+ local file="$1"
+
+ if [ "$logrotate_max" = "" ]; then
+ return
+ elif [ "$logrotate_max" -le 0 ]; then
+ return
+ fi
+
+ for number in $(seq $logrotate_max 0)
+ do
+ next=$(($number + 1))
+ if [ -e "$file.$number.gz" -a $next -lt $logrotate_max ]; then
+ mv -f "$file.$number.gz" "$file.$next.gz"
+ fi
+ done
+ if [ -e "$file" ]; then
+ mv "$file" "$file.0"
+ gzip -f "$file.0"
+ fi
+}
+
+decho() {
+ local message="$1"
+ # -1 | 0 | 1 - use -1 to always show error messages
+ local d="$2"
+ # log to stdout and the logfile
+ local stdout="$3"
+
+ if [ -z "$d" ]; then
+ d="0"
+ fi
+
+ # debug messages to stderr
+ if [ $debug -gt $d ]; then
+ echo "-- $message" >&2
+ fi
+
+ # debug messages to logfile
+ if [ -n "$stdout" ]; then
+ echo "$message"
+ fi
+}
+
+: ${build_clean_delay=4}
+if [ "$build_clean" = "YES" ]; then
+ decho "cleanup obj files in ${build_clean_delay} seconds"
+ decho "MAKEOBJDIRPREFIX=$MAKEOBJDIRPREFIX"
+
+ # last change to hit ^C
+ for i in $(seq 1 ${build_clean_delay})
+ do
+ printf "."; sleep 1
+ done
+ echo ""
+
+ rm -rf $MAKEOBJDIRPREFIX
+else
+ decho "set MAKEOBJDIRPREFIX=$MAKEOBJDIRPREFIX"
+fi
+mkdir -p $MAKEOBJDIRPREFIX
+
+logrotate "macos.setup"
+# log infos about macOS setup
+(
+echo "Start time: $(date)"
+sysctl machdep.cpu.brand_string
+sysctl kern.osproductversion
+echo "$(sysctl hw.physicalcpu) / P-cores: $(sysctl hw.perflevel0.physicalcpu) / E-cores: $(sysctl hw.perflevel1.physicalcpu)"
+sysctl hw.memsize | awk '{ printf("%s %2.1f GB\n", $1, $2/1024/1024/1024) }'
+
+echo "Xcode path: $(xcode-select -p)"
+echo "Xcode version: $(pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep '^version: ')"
+
+if [ -d $clt_sdk_dir ]; then
+ echo "SDK version: $(ls -l $clt_sdk_dir)"
+fi
+
+if [ -d .git ]; then
+ decho "local git branch: $(git branch | grep '^\*' | sed -e 's/^\* //')" 0 stdout
+ decho "last git commit: $(git log --oneline | head -n1)" 0 stdout
+fi
+
+# program version
+cat <<EOF
+
+PATH=$PATH
+
+clang path: $(which clang)
+installed at $(ls -lL $(which clang))
+$(clang --version)
+
+linker path: $(which ld.lld)
+installed at $(ls -lL $(which ld.lld))
+$(ld.lld -v 2>&1)
+EOF
+
+# env variables for cross compiling
+cat <<EOF
+
+TARGET=$TARGET TARGET_ARCH=$TARGET_ARCH
+
+CC=$CC
+CXX=$CXX
+CPP=$CPP
+XCC=$XCC
+XCXX=$XCXX
+XCPP=$XCPP
+XLD=$XLD
+EOF
+
+if [ -n "$TAR_XZ_CMD" -o -n "$PKG_FORMAT" ]; then
+ echo "TAR_XZ_CMD=$TAR_XZ_CMD"
+ echo "PKG_FORMAT=$PKG_FORMAT"
+fi
+
+case $homebrew_llvm_version in
+ @19 | @20) ;;
+ *) decho "warning: unsupported homebrew_llvm_version='$homebrew_llvm_version', only '@19' and '@20' are supported" 0 x;;
+esac
+
+if [ "$build_show_du" = "YES" ]; then
+ echo ""
+ echo "current MAKEOBJDIRPREFIX disk usage: $(du -hs $MAKEOBJDIRPREFIX)"
+fi
+echo "ncpu=$ncpu"
+
+echo ""
+if [ -n "$build_targets_opt" ]; then
+ decho "build_fast=$build_fast with make parameters: $build_targets_opt" 0 stdout
+fi
+echo ""
+decho "now run for ${TARGET}/${TARGET_ARCH} build_targets=\"${build_targets}\"" 0 stdout
+) > macos.setup
+
+#
+# build FreeBSD world and kernel
+#
+# expected runtime without TOOLCHAIN (build_fast="YES") for
+# iMac (Intel Core i5, 2019, 6-cores) ca. 119min
+# MacBook Air (M1, 2020, 4P/4E cores) ca. 42min
+# MacBook Pro (M1, 2021, 8P/2E cores) ca. 21min
+#
+# with TOOLCHAIN (build_fast="NO") it will be 2x slower
+#
+(
+set -e
+
+OLD_IFS=$IFS
+IFS=";"
+
+for target in $build_targets
+do
+ IFS=$OLD_IFS
+ log=$(echo $target | sed -E -e 's/[ ]?\-[^ ]+[ ]//; s/ /-/g; s/\//-/g')
+
+ # keep logs from previous run
+ logrotate "macos.$log"
+
+ decho "start target '$target' at $(date)" 0 x >> macos.setup
+
+ # cross compiling
+ if $nice_cmd ./tools/build/make.py -j$ncpu TARGET=$TARGET TARGET_ARCH=$TARGET_ARCH $build_targets_opt $target > macos.$log 2>&1; then
+ :
+ else
+ exit=$?
+
+ # keep track of bad git commits
+ git log --oneline | head -n1 > ".cross-build-macos-git-bad"
+
+ decho "make target '$target' failed with exit status: $exit - see the log file ./macos.$log" -1 x >> macos.setup
+ exit $exit
+ fi
+done
+)
+
+(
+ if [ "$build_show_du" = "YES" ]; then
+ echo ""
+ echo "MAKEOBJDIRPREFIX disk usage:"
+ du -hs $MAKEOBJDIRPREFIX
+ fi
+
+ # keep track of good git commits
+ git log --oneline | head -n1 > ".cross-build-macos-git-good"
+
+ echo ""
+ decho ">>> Build of target(s) $build_targets were successfully executed at $(date) <<<" 0 stdout
+) >> macos.setup
+
+#EOF

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 31, 7:42 AM (7 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28109841
Default Alt Text
D51087.diff (9 KB)

Event Timeline