From 460b3fe9e235483eb97437b856fba6f45f7588a8 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Wed, 17 Aug 2022 16:09:02 +0200 Subject: [PATCH] build: ship universal binaries for macOS This mostly reverts commit 737afb3517d822ae50722510993acbd097bc5aca. We have to build in an OOT directory to make it work. This also requires to bump minimum SDK to 11.1 (for ARM64 mostly but it also fix an issue with strtonum() which is detected as available but really is since 11.0 only). This does not currently work as the host has to be ARM64 (to be able to run both binaries). Otherwise, we would have to cross-compile. See https://github.com/actions/runner-images/issues/2187 for availability. --- .github/workflows/ci.yml | 6 ++-- NEWS | 4 +++ README.md | 29 +++++++------------ osx/Makefile.am | 19 +++++++++++-- osx/lipo | 60 ++++++++++++++++++++++++++++++++++++++++ tests/ci/run.sh | 11 ++++---- 6 files changed, 99 insertions(+), 30 deletions(-) create mode 100755 osx/lipo diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 956e2211..ec54aee5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,13 +50,13 @@ jobs: CC: ${{ matrix.compiler }} - name: Generate release body if: matrix.release - run: ./tests/ci/release.sh > release.md + run: cd build && ../tests/ci/release.sh > ../release.md - name: Upload release tarball uses: actions/upload-artifact@v2 if: matrix.release with: name: tarball - path: lldpd-*.tar.gz + path: build/lldpd-*.tar.gz if-no-files-found: error - name: Upload release summary uses: actions/upload-artifact@v2 @@ -97,7 +97,7 @@ jobs: if: matrix.release with: name: package - path: lldpd-*.pkg + path: build/lldpd-*.pkg if-no-files-found: error build-bsd: diff --git a/NEWS b/NEWS index ee9c8851..fdc828c2 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +lldpd (1.0.16) + * Changes + + Ship universal binaries for MacOS (x86_64 and arm64) + lldpd (1.0.15) * Changes + Add configure command to override system capabilities. Contributed by diff --git a/README.md b/README.md index f02838ab..c57353ac 100644 --- a/README.md +++ b/README.md @@ -92,38 +92,29 @@ simpler alternatives: # Or, for the latest version: brew install https://raw.github.com/lldpd/lldpd/master/osx/lldpd.rb - 2. Build an macOS installer package which should work on the same - version of macOS: - + 2. Build an OS X installer package which should work on the same + version of OS X (it is important to use a separate build + directory): + mkdir build && cd build ../configure --prefix=/usr/local --localstatedir=/var --sysconfdir=/private/etc --with-embedded-libevent \ --without-snmp make -C osx pkg If you want to compile for an older version of macOS, you need - to find the right SDK and issues commands like those: - - SDK=/Developer/SDKs/MacOSX10.6.sdk - mkdir build && cd build - ../configure --prefix=/usr/local --localstatedir=/var --sysconfdir=/private/etc --with-embedded-libevent \ - --without-snmp \ - CFLAGS="-mmacosx-version-min=10.6 -isysroot $SDK" \ - LDFLAGS="-mmacosx-version-min=10.6 -isysroot $SDK" - make -C osx pkg - - With recent SDK, you don't need to specify an alternate SDK. They - are organized in a way that should enable compatibility with older - versions of OSX: + commands like those: mkdir build && cd build ../configure --prefix=/usr/local --localstatedir=/var --sysconfdir=/private/etc --with-embedded-libevent \ --without-snmp \ - CFLAGS="-mmacosx-version-min=10.9" \ - LDFLAGS="-mmacosx-version-min=10.9" + CFLAGS="-mmacosx-version-min=11.1" \ + LDFLAGS="-mmacosx-version-min=11.1" make -C osx pkg You can check with `otool -l` that you got what you expected in - term of supported versions. + term of supported versions. If you are running on ARM64, you can + configure a binary supporting both architectures by adding + `ARCHS="arm64 x86_64"` to the arguments of the `make` command. If you don't follow the above procedures, you will have to create the user/group `_lldpd`. Have a look at how this is done in diff --git a/osx/Makefile.am b/osx/Makefile.am index 7d128cf3..7f152e1c 100644 --- a/osx/Makefile.am +++ b/osx/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = resources +EXTRA_DIST = resources lipo EXTRA_DIST += distribution.xml.in im.bernat.lldpd.plist.in scripts/postinstall.in scripts/preinstall.in TEMPLATES = distribution.xml im.bernat.lldpd.plist scripts/postinstall scripts/preinstall @@ -14,6 +14,7 @@ requirements: PKG_NAME=@PACKAGE@-@VERSION@.pkg PKG_TITLE=@PACKAGE@ @VERSION@ PKG_DIR=@PACKAGE@-@VERSION@ +ARCHS=@host_cpu@ # Main target is `pkg` pkg: requirements ../$(PKG_NAME) @@ -42,8 +43,20 @@ pkg.1/$(PKG_NAME): $(PKG_DIR) scripts/postinstall scripts/preinstall $@ $(PKG_DIR): stamp-$(PKG_DIR) -stamp-$(PKG_DIR): im.bernat.lldpd.plist - $(MAKE) -C .. install DESTDIR=$(abs_builddir)/$(PKG_DIR) +stamp-$(PKG_DIR): $(ARCHS:%=%/$(PKG_DIR)) + $(srcdir)/lipo $(PKG_DIR) $^ + touch $@ + +pkg_curarch = $(@:stamp-%=%) +$(ARCHS:%=%/$(PKG_DIR)): %/$(PKG_DIR): stamp-% +$(ARCHS:%=stamp-%): stamp-%: im.bernat.lldpd.plist + [ -d $(pkg_curarch) ] || mkdir -p $(pkg_curarch) + (cd $(pkg_curarch) && \ + $(abs_top_srcdir)/configure @CONFIGURE_ARGS@ \ + CC="@CC@ -arch $(pkg_curarch)" \ + CPP="@CPP@") + (cd $(pkg_curarch) && \ + $(MAKE) install DESTDIR=$(abs_builddir)/$(pkg_curarch)/$(PKG_DIR)) touch $@ # Install launchd plist diff --git a/osx/lipo b/osx/lipo new file mode 100755 index 00000000..80e658af --- /dev/null +++ b/osx/lipo @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +"""Apply lipo recursively to trees. +""" + +import sys +import os +import shutil +import subprocess + +# Parse arguments +import argparse + +parser = argparse.ArgumentParser( + description=sys.modules[__name__].__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, +) +parser.add_argument("output", help="Output tree") +parser.add_argument("input", help="Input trees", nargs="+") +options = parser.parse_args() +output = options.output +inputs = options.input + + +def ismacho(path): + """Check if a file is Mach-O""" + fnull = open(os.devnull, "w") + try: + subprocess.check_call(["lipo", "-info", path], stdout=fnull, stderr=fnull) + except subprocess.CalledProcessError: + return False + return True + + +# Copy +for root, dirs, files in os.walk(inputs[0]): + # Create root directory in output + oroot = root[len(inputs[0]) :].lstrip("/") + oroot = os.path.join(output, oroot) + if not os.path.isdir(oroot): + os.makedirs(oroot) + shutil.copystat(root, oroot) + + # Copy files + for f in files: + of = os.path.join(oroot, f) + f = os.path.join(root, f) + if os.path.islink(f): + # Symlink + linkto = os.readlink(f) + os.symlink(linkto, of) + elif ismacho(f): + sff = [os.path.join(r, f[len(inputs[0]) :].lstrip("/")) for r in inputs] + args = ["lipo", "-create", "-output", of] + args.extend(sff) + subprocess.check_call(args) + else: + # Regular file, just copy from the first input directory + shutil.copyfile(f, of) + shutil.copystat(f, of) diff --git a/tests/ci/run.sh b/tests/ci/run.sh index 332fedac..67ebdd6f 100755 --- a/tests/ci/run.sh +++ b/tests/ci/run.sh @@ -12,8 +12,8 @@ case "$(uname -s)" in MAKE_ARGS="-Werror" ;; Darwin) - LLDPD_CONFIG_ARGS="$LLDPD_CONFIG_ARGS CFLAGS=-mmacosx-version-min=10.9" - LLDPD_CONFIG_ARGS="$LLDPD_CONFIG_ARGS LDFLAGS=-mmacosx-version-min=10.9" + LLDPD_CONFIG_ARGS="$LLDPD_CONFIG_ARGS CFLAGS=-mmacosx-version-min=11.1" + LLDPD_CONFIG_ARGS="$LLDPD_CONFIG_ARGS LDFLAGS=-mmacosx-version-min=11.1" MAKE_ARGS="" ;; OpenBSD) @@ -23,7 +23,8 @@ case "$(uname -s)" in esac ./autogen.sh -./configure $LLDPD_CONFIG_ARGS || { +mkdir build && cd build +../configure $LLDPD_CONFIG_ARGS || { cat config.log exit 1 } @@ -40,12 +41,12 @@ fi case "$(uname -s)" in Darwin) # Create a package - make -C osx pkg + make -C osx pkg ARCHS="x86_64 arm64" otool -l osx/lldpd*/usr/local/sbin/lldpd ;; Linux) # Integration tests - cd tests/integration + cd ../tests/integration sudo $(which python3) -m pytest -n 5 -vv --boxed || \ sudo $(which python3) -m pytest -vvv --last-failed --maxfail=5 ;; -- 2.39.5