From c62cdf810a7deb8227c5e63f96d158324abe59ba Mon Sep 17 00:00:00 2001 From: spectrum Date: Tue, 12 May 2026 00:56:34 +0300 Subject: [PATCH 1/9] Build macOS prebuilts for arm64 and x86_64 --- .github/workflows/deploy.yml | 1 + cmake/platform_settings.cmake | 2 +- recipes/amnezia-xray-bindings/conanfile.py | 127 +++++++++++++++++++-- recipes/awg-go/conanfile.py | 75 +++++++++++- recipes/tun2socks/conanfile.py | 87 ++++++++++++-- 5 files changed, 265 insertions(+), 27 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6784b69b11..0317a464f6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -408,6 +408,7 @@ jobs: if: needs.Detect-Changes.outputs.recipes_changed == 'true' strategy: + max-parallel: 1 matrix: xcode-version: [16.2, 16.4, 26.4] include: diff --git a/cmake/platform_settings.cmake b/cmake/platform_settings.cmake index f561d55749..a9351aa4aa 100644 --- a/cmake/platform_settings.cmake +++ b/cmake/platform_settings.cmake @@ -12,7 +12,7 @@ if(APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) else() set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE) - set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "" FORCE) + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) endif() endif() diff --git a/recipes/amnezia-xray-bindings/conanfile.py b/recipes/amnezia-xray-bindings/conanfile.py index fb7d6a53bb..3c903d167f 100644 --- a/recipes/amnezia-xray-bindings/conanfile.py +++ b/recipes/amnezia-xray-bindings/conanfile.py @@ -3,13 +3,17 @@ from conan.tools.layout import basic_layout from conan.errors import ConanInvalidConfiguration from conan.tools.gnu import Autotools, AutotoolsToolchain +from conan.tools.env import VirtualBuildEnv import os +import shlex + class AmneziaXrayBindings(ConanFile): name = "amnezia-xray-bindings" version = "1.1.0" settings = "os", "arch", "compiler" + _lib_name = "libamnezia_xray.a" @property def _goos(self): @@ -19,15 +23,108 @@ def _goos(self): "Macos": "darwin", "Windows": "windows" }.get(str(self.settings.os)) - + @property - def _goarch(self): + def _arch_map(self): return { "x86": "386", "x86_64": "amd64", "armv8": "arm64" - }.get(str(self.settings.arch)) - + } + + @property + def _apple_arch_map(self): + return { + "x86_64": "x86_64", + "armv8": "arm64", + } + + @property + def _archs(self): + return str(self.settings.arch).split("|") + + @property + def _goarch(self): + goarchs = [self._arch_map.get(arch) for arch in self._archs] + return goarchs[0] if len(goarchs) == 1 else None + + @property + def _goarchs(self): + return [self._arch_map.get(arch) for arch in self._archs] + + @property + def _is_universal_macos(self): + return str(self.settings.os) == "Macos" and len(self._archs) > 1 + + @property + def _is_unsupported_multi_arch(self): + return len(self._archs) > 1 and not self._is_universal_macos + + def _go_cache_vars(self): + return { + "GOPATH": os.path.join(self.build_folder, "gopath"), + "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), + "GOCACHE": os.path.join(self.build_folder, "gocache"), + "GOTELEMETRY": "off", + } + + def _define_go_cache_env(self, env): + for name, value in self._go_cache_vars().items(): + env.define(name, value) + + def _go_cache_make_args(self): + return [f"{name}={value}" for name, value in self._go_cache_vars().items()] + + def _non_arch_flags(self, flags): + tokens = [] + for flag in flags: + tokens.extend(shlex.split(flag)) + + result = [] + skip_next = False + for flag in tokens: + if skip_next: + skip_next = False + elif flag == "-arch": + skip_next = True + else: + result.append(flag) + return result + + def _cgo_flags(self, arch, flags): + return " ".join(["-arch", self._apple_arch_map[arch]] + self._non_arch_flags(flags)) + + def _make_var(self, name, value): + return f"{name}={shlex.quote(value)}" + + def _go_arch_make_args(self, arch, goarch): + tc = AutotoolsToolchain(self) + return self._go_cache_make_args() + [ + f"GOOS={self._goos}", + f"GOARCH={goarch}", + f"ARCH={goarch}", + self._make_var("CGO_CFLAGS", self._cgo_flags(arch, tc.cflags)), + self._make_var("CGO_LDFLAGS", self._cgo_flags(arch, tc.ldflags)), + ] + + def _build_go_arch(self, arch, goarch): + with chdir(self, self.source_folder): + autotools = Autotools(self) + autotools.make(args=self._go_arch_make_args(arch, goarch)) + + output_path = os.path.join(self.build_folder, self._lib_name) + if not os.path.exists(output_path): + output_path = os.path.join(self.source_folder, self._lib_name) + + arch_output_path = os.path.join(self.build_folder, f"libamnezia_xray-{goarch}.a") + os.rename(output_path, arch_output_path) + return arch_output_path + + def _build_universal_macos(self): + outputs = [self._build_go_arch(arch, goarch) for arch, goarch in zip(self._archs, self._goarchs)] + universal_output = os.path.join(self.build_folder, self._lib_name) + self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") + @property def _is_windows(self): return str(self.settings.os).startswith("Windows") @@ -54,7 +151,7 @@ def build_requirements(self): self.tool_requires("mingw-builds/15.1.0") def validate(self): - if not self._goos or not self._goarch: + if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) @@ -64,21 +161,28 @@ def source(self): sha256="6ea768ec7002cedd422a39aea17704b888acaf794432aa5937cfc92fb6d80eb5", strip_root=True) def generate(self): + VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) tc.make_args = [ "LIB_ARC=libamnezia_xray.a" ] env = tc.environment() - env.define("ARCH", self._goarch) - env.define("GOARCH", self._goarch) + self._define_go_cache_env(env) + if not self._is_universal_macos: + env.define("ARCH", self._goarch) + env.define("GOARCH", self._goarch) + env.define("CGO_LDFLAGS", tc.ldflags) + env.define("CGO_CFLAGS", tc.cflags) env.define("GOOS", self._goos) - env.define("CGO_LDFLAGS", tc.ldflags) - env.define("CGO_CFLAGS", tc.cflags) if self._is_windows: env.define("OS", "windows") tc.generate(env) def build(self): + if self._is_universal_macos: + self._build_universal_macos() + return + with chdir(self, self.source_folder): autotools = Autotools(self) autotools.make() @@ -100,7 +204,10 @@ def _rename_libs(self): def package(self): copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include")) - copy(self, "*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) + if self._is_universal_macos: + copy(self, self._lib_name, src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) + else: + copy(self, "*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) copy(self, "*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin")) self._rename_header() diff --git a/recipes/awg-go/conanfile.py b/recipes/awg-go/conanfile.py index ae39623e65..ac2804533a 100644 --- a/recipes/awg-go/conanfile.py +++ b/recipes/awg-go/conanfile.py @@ -3,14 +3,17 @@ from conan.tools.layout import basic_layout from conan.tools.files import get, copy from conan.tools.gnu import Autotools, AutotoolsToolchain +from conan.tools.env import VirtualBuildEnv import os + class AwgGo(ConanFile): name = "awg-go" version = "0.2.16" package_type = "application" settings = "os", "arch" + _binary_name = "amneziawg-go" @property def _goos(self): @@ -21,12 +24,65 @@ def _goos(self): }.get(str(self.settings.os)) @property - def _goarch(self): + def _arch_map(self): return { "x86": "386", "x86_64": "amd64", "armv8": "arm64" - }.get(str(self.settings.arch)) + } + + @property + def _archs(self): + return str(self.settings.arch).split("|") + + @property + def _goarch(self): + goarchs = [self._arch_map.get(arch) for arch in self._archs] + return goarchs[0] if len(goarchs) == 1 else None + + @property + def _goarchs(self): + return [self._arch_map.get(arch) for arch in self._archs] + + @property + def _is_universal_macos(self): + return str(self.settings.os) == "Macos" and len(self._archs) > 1 + + @property + def _is_unsupported_multi_arch(self): + return len(self._archs) > 1 and not self._is_universal_macos + + def _go_cache_vars(self): + return { + "GOPATH": os.path.join(self.build_folder, "gopath"), + "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), + "GOCACHE": os.path.join(self.build_folder, "gocache"), + "GOTELEMETRY": "off", + } + + def _define_go_cache_env(self, env): + for name, value in self._go_cache_vars().items(): + env.define(name, value) + + def _go_arch_make_args(self, goarch): + return [f"{name}={value}" for name, value in self._go_cache_vars().items()] + [ + f"GOOS={self._goos}", + f"GOARCH={goarch}", + ] + + def _build_go_arch(self, goarch): + autotools = Autotools(self) + autotools.make(args=self._go_arch_make_args(goarch)) + + output_path = os.path.join(self.build_folder, self._binary_name) + arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") + os.rename(output_path, arch_output_path) + return arch_output_path + + def _build_universal_macos(self): + outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] + universal_output = os.path.join(self.build_folder, self._binary_name) + self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") def layout(self): basic_layout(self, build_folder=".") @@ -35,7 +91,7 @@ def build_requirements(self): self.tool_requires("go/1.26.0") def validate(self): - if not self._goos or not self._goarch: + if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) @@ -46,22 +102,29 @@ def source(self): ) def generate(self): + VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) env = tc.environment() + self._define_go_cache_env(env) env.define("GOOS", self._goos) - env.define("GOARCH", self._goarch) + if not self._is_universal_macos: + env.define("GOARCH", self._goarch) env.define("CGO_LDFLAGS", tc.ldflags) env.define("CGO_CFLAGS", tc.cflags) tc.generate(env) def build(self): + if self._is_universal_macos: + self._build_universal_macos() + return + at = Autotools(self) at.make() def package(self): - copy(self, "amneziawg-go", src=self.build_folder, dst=self.package_folder) + copy(self, self._binary_name, src=self.build_folder, dst=self.package_folder) def package_info(self): self.cpp_info.exe = True - self.cpp_info.location = os.path.join(self.package_folder, "amneziawg-go") + self.cpp_info.location = os.path.join(self.package_folder, self._binary_name) self.cpp_info.set_property("cmake_target_name", "amnezia::awg-go") diff --git a/recipes/tun2socks/conanfile.py b/recipes/tun2socks/conanfile.py index 417bcfd101..4df179922f 100644 --- a/recipes/tun2socks/conanfile.py +++ b/recipes/tun2socks/conanfile.py @@ -3,15 +3,17 @@ from conan.tools.files import get, copy, chdir from conan.errors import ConanInvalidConfiguration from conan.tools.gnu import Autotools, AutotoolsToolchain -from conan.tools.env import Environment +from conan.tools.env import VirtualBuildEnv import os + class Tun2Socks(ConanFile): name = "tun2socks" version = "2.6.0" package_type = "application" settings = "os", "arch" + _binary_name = "tun2socks" @property def _goos(self): @@ -22,17 +24,75 @@ def _goos(self): }.get(str(self.settings.os)) @property - def _goarch(self): + def _arch_map(self): return { "x86": "386", "x86_64": "amd64", "armv8": "arm64" - }.get(str(self.settings.arch)) - + } + + @property + def _archs(self): + return str(self.settings.arch).split("|") + + @property + def _goarch(self): + goarchs = [self._arch_map.get(arch) for arch in self._archs] + return goarchs[0] if len(goarchs) == 1 else None + + @property + def _goarchs(self): + return [self._arch_map.get(arch) for arch in self._archs] + + @property + def _is_universal_macos(self): + return str(self.settings.os) == "Macos" and len(self._archs) > 1 + + @property + def _is_unsupported_multi_arch(self): + return len(self._archs) > 1 and not self._is_universal_macos + + def _go_cache_vars(self): + return { + "GOPATH": os.path.join(self.build_folder, "gopath"), + "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), + "GOCACHE": os.path.join(self.build_folder, "gocache"), + "GOTELEMETRY": "off", + } + + def _define_go_cache_env(self, env): + for name, value in self._go_cache_vars().items(): + env.define(name, value) + + def _go_arch_make_args(self, goarch): + return [f"{name}={value}" for name, value in self._go_cache_vars().items()] + [ + "LDFLAGS=", + f"GOOS={self._goos}", + f"GOARCH={goarch}", + ] + + def _build_go_arch(self, goarch): + with chdir(self, self.source_folder): + autotools = Autotools(self) + autotools.make(self._binary_name, args=self._go_arch_make_args(goarch)) + + output_path = os.path.join(self.build_folder, self._binary_name) + if not os.path.exists(output_path): + output_path = os.path.join(self.source_folder, self._binary_name) + + arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") + os.rename(output_path, arch_output_path) + return arch_output_path + + def _build_universal_macos(self): + outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] + universal_output = os.path.join(self.build_folder, self._binary_name) + self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") + @property def _is_windows(self): return str(self.settings.get_safe("os")).startswith("Windows") - + @property def _ext(self): return ".exe" if self._is_windows else "" @@ -41,7 +101,7 @@ def layout(self): basic_layout(self) def validate(self): - if not self._goos or not self._goarch: + if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) @@ -64,25 +124,32 @@ def source(self): ) def generate(self): + VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) env = tc.environment() + self._define_go_cache_env(env) env.define("LDFLAGS", "") env.define("CGO_LDFLAGS", tc.ldflags) env.define("CGO_CFLAGS", tc.cflags) env.define("GOOS", self._goos) - env.define("GOARCH", self._goarch) + if not self._is_universal_macos: + env.define("GOARCH", self._goarch) tc.generate(env) def build(self): + if self._is_universal_macos: + self._build_universal_macos() + return + with chdir(self, self.source_folder): at = Autotools(self) - at.make("tun2socks") + at.make(self._binary_name) def package(self): - copy(self, "tun2socks", src=self.build_folder, dst=self.package_folder) + copy(self, self._binary_name, src=self.build_folder, dst=self.package_folder) if self._is_windows: with chdir(self, self.package_folder): - os.rename(src="tun2socks", dst="tun2socks.exe") + os.rename(src=self._binary_name, dst=f"{self._binary_name}.exe") def package_info(self): self.cpp_info.exe = True From ca54ddcc83b6dec1982ed3111fa737ba229081fc Mon Sep 17 00:00:00 2001 From: Yaroslav Gurov Date: Mon, 25 May 2026 09:45:13 +0200 Subject: [PATCH 2/9] chore: remove parallel thingy from CI/CD --- .github/workflows/deploy.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0317a464f6..6784b69b11 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -408,7 +408,6 @@ jobs: if: needs.Detect-Changes.outputs.recipes_changed == 'true' strategy: - max-parallel: 1 matrix: xcode-version: [16.2, 16.4, 26.4] include: From 01227fbd7260d292c085b6f973099800bc5eb25c Mon Sep 17 00:00:00 2001 From: Yaroslav Gurov Date: Mon, 25 May 2026 10:10:40 +0200 Subject: [PATCH 3/9] feat: rework amnezia-xray-bindings for multiarch --- recipes/amnezia-xray-bindings/conanfile.py | 175 +++++++-------------- 1 file changed, 54 insertions(+), 121 deletions(-) diff --git a/recipes/amnezia-xray-bindings/conanfile.py b/recipes/amnezia-xray-bindings/conanfile.py index 3c903d167f..38c33b8862 100644 --- a/recipes/amnezia-xray-bindings/conanfile.py +++ b/recipes/amnezia-xray-bindings/conanfile.py @@ -1,19 +1,26 @@ from conan import ConanFile -from conan.tools.files import get, copy, collect_libs, chdir, rename +from conan.tools.files import get, copy, collect_libs, chdir, rename, mkdir from conan.tools.layout import basic_layout from conan.errors import ConanInvalidConfiguration from conan.tools.gnu import Autotools, AutotoolsToolchain -from conan.tools.env import VirtualBuildEnv +from conan.tools.apple import XCRun, is_apple_os +from conan.tools.apple.apple import _to_apple_arch +from conan.tools.files.copy_pattern import _filter_files import os -import shlex +from pathlib import Path class AmneziaXrayBindings(ConanFile): name = "amnezia-xray-bindings" version = "1.1.0" settings = "os", "arch", "compiler" - _lib_name = "libamnezia_xray.a" + + _arch_map = { + "x86": "386", + "x86_64": "amd64", + "armv8": "arm64" + } @property def _goos(self): @@ -24,106 +31,13 @@ def _goos(self): "Windows": "windows" }.get(str(self.settings.os)) - @property - def _arch_map(self): - return { - "x86": "386", - "x86_64": "amd64", - "armv8": "arm64" - } - - @property - def _apple_arch_map(self): - return { - "x86_64": "x86_64", - "armv8": "arm64", - } - @property def _archs(self): return str(self.settings.arch).split("|") - - @property - def _goarch(self): - goarchs = [self._arch_map.get(arch) for arch in self._archs] - return goarchs[0] if len(goarchs) == 1 else None - - @property - def _goarchs(self): - return [self._arch_map.get(arch) for arch in self._archs] - - @property - def _is_universal_macos(self): - return str(self.settings.os) == "Macos" and len(self._archs) > 1 - + @property - def _is_unsupported_multi_arch(self): - return len(self._archs) > 1 and not self._is_universal_macos - - def _go_cache_vars(self): - return { - "GOPATH": os.path.join(self.build_folder, "gopath"), - "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), - "GOCACHE": os.path.join(self.build_folder, "gocache"), - "GOTELEMETRY": "off", - } - - def _define_go_cache_env(self, env): - for name, value in self._go_cache_vars().items(): - env.define(name, value) - - def _go_cache_make_args(self): - return [f"{name}={value}" for name, value in self._go_cache_vars().items()] - - def _non_arch_flags(self, flags): - tokens = [] - for flag in flags: - tokens.extend(shlex.split(flag)) - - result = [] - skip_next = False - for flag in tokens: - if skip_next: - skip_next = False - elif flag == "-arch": - skip_next = True - else: - result.append(flag) - return result - - def _cgo_flags(self, arch, flags): - return " ".join(["-arch", self._apple_arch_map[arch]] + self._non_arch_flags(flags)) - - def _make_var(self, name, value): - return f"{name}={shlex.quote(value)}" - - def _go_arch_make_args(self, arch, goarch): - tc = AutotoolsToolchain(self) - return self._go_cache_make_args() + [ - f"GOOS={self._goos}", - f"GOARCH={goarch}", - f"ARCH={goarch}", - self._make_var("CGO_CFLAGS", self._cgo_flags(arch, tc.cflags)), - self._make_var("CGO_LDFLAGS", self._cgo_flags(arch, tc.ldflags)), - ] - - def _build_go_arch(self, arch, goarch): - with chdir(self, self.source_folder): - autotools = Autotools(self) - autotools.make(args=self._go_arch_make_args(arch, goarch)) - - output_path = os.path.join(self.build_folder, self._lib_name) - if not os.path.exists(output_path): - output_path = os.path.join(self.source_folder, self._lib_name) - - arch_output_path = os.path.join(self.build_folder, f"libamnezia_xray-{goarch}.a") - os.rename(output_path, arch_output_path) - return arch_output_path - - def _build_universal_macos(self): - outputs = [self._build_go_arch(arch, goarch) for arch, goarch in zip(self._archs, self._goarchs)] - universal_output = os.path.join(self.build_folder, self._lib_name) - self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") + def _is_multiarch(self): + return len(self._archs) > 1 @property def _is_windows(self): @@ -151,41 +65,62 @@ def build_requirements(self): self.tool_requires("mingw-builds/15.1.0") def validate(self): - if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: + if not self._goos or not all(arch in self._arch_map for arch in self._archs): raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) + + if self._is_multiarch and not is_apple_os(self): + raise ConanInvalidConfiguration( + f"{self.name} v{self.version} does not support multiarch builds" + ) def source(self): get(self, "https://github.com/amnezia-vpn/amnezia-xray-bindings/archive/v1.1.0.zip", sha256="6ea768ec7002cedd422a39aea17704b888acaf794432aa5937cfc92fb6d80eb5", strip_root=True) def generate(self): - VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) + tc.apple_arch_flag = None tc.make_args = [ "LIB_ARC=libamnezia_xray.a" ] env = tc.environment() - self._define_go_cache_env(env) - if not self._is_universal_macos: - env.define("ARCH", self._goarch) - env.define("GOARCH", self._goarch) - env.define("CGO_LDFLAGS", tc.ldflags) - env.define("CGO_CFLAGS", tc.cflags) + env.define("GOPATH", os.path.join(self.build_folder, "gopath")) + env.define("GOMODCACHE", os.path.join(self.build_folder, "gopath", "pkg", "mod")) + env.define("GOCACHE", os.path.join(self.build_folder, "gocache")) env.define("GOOS", self._goos) if self._is_windows: env.define("OS", "windows") + self._ldflags = tc.ldflags + self._cflags = tc.cflags tc.generate(env) def build(self): - if self._is_universal_macos: - self._build_universal_macos() - return - with chdir(self, self.source_folder): - autotools = Autotools(self) - autotools.make() + for arch in self._archs: + cflags = self._cflags + ldflags = self._ldflags + if is_apple_os(self): + cflags.append(f"-arch {_to_apple_arch(arch)}") + ldflags.append(f"-arch {_to_apple_arch(arch)}") + + autotools = Autotools(self) + autotools.make(args=[ + f"BUILD_DIR={os.path.join("build", arch)}" + f"ARCH={self._arch_map.get(arch)}", + f"CGO_CFLAGS={cflags}", + f"CGO_LDFLAGS={ldflags}" + ]) + + if is_apple_os(self) and self._is_multiarch: + dir = os.path.join(self.source_folder, "merged") + archives = _filter_files(self.source_folder, "*.a", None, False, dir) + output = os.path.join(dir, Path(archives[0]).name) + + mkdir(dir) + lipo = XCRun(self).find('lipo') + self.run(f"{lipo} -create -output {output} {archives}") def _rename_header(self): if not self._is_windows: @@ -203,13 +138,11 @@ def _rename_libs(self): os.rename(src, dst) def package(self): - copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include")) - if self._is_universal_macos: - copy(self, self._lib_name, src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) - else: - copy(self, "*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) - copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib")) - copy(self, "*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin")) + dir_pattern = os.path.join("build", "merged") if self._is_multiarch else os.path.join("build", "*") + copy(self, os.path.join(dir_pattern, "*.h"), src=self.build_folder, dst=os.path.join(self.package_folder, "include"), keep_path=False) + copy(self, os.path.join(dir_pattern, "*.a"), src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) + copy(self, os.path.join(dir_pattern, "*.lib"), src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) + copy(self, os.path.join(dir_pattern, "*.dll"), src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False) self._rename_header() def package_info(self): From cbecca407c4b8b9c48f267adb986adb93e9bb5f5 Mon Sep 17 00:00:00 2001 From: spectrum Date: Tue, 26 May 2026 15:50:10 +0300 Subject: [PATCH 4/9] Fix macOS universal recipe builds --- recipes/amnezia-xray-bindings/conanfile.py | 49 +++++++++++++--------- recipes/awg-go/conanfile.py | 9 +++- recipes/tun2socks/conanfile.py | 11 ++++- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/recipes/amnezia-xray-bindings/conanfile.py b/recipes/amnezia-xray-bindings/conanfile.py index 38c33b8862..332a89c567 100644 --- a/recipes/amnezia-xray-bindings/conanfile.py +++ b/recipes/amnezia-xray-bindings/conanfile.py @@ -5,9 +5,9 @@ from conan.tools.gnu import Autotools, AutotoolsToolchain from conan.tools.apple import XCRun, is_apple_os from conan.tools.apple.apple import _to_apple_arch -from conan.tools.files.copy_pattern import _filter_files import os +import shlex from pathlib import Path @@ -34,7 +34,7 @@ def _goos(self): @property def _archs(self): return str(self.settings.arch).split("|") - + @property def _is_multiarch(self): return len(self._archs) > 1 @@ -69,7 +69,7 @@ def validate(self): raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) - + if self._is_multiarch and not is_apple_os(self): raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support multiarch builds" @@ -99,28 +99,38 @@ def generate(self): def build(self): with chdir(self, self.source_folder): for arch in self._archs: - cflags = self._cflags - ldflags = self._ldflags + cflags = list(self._cflags) + ldflags = list(self._ldflags) if is_apple_os(self): cflags.append(f"-arch {_to_apple_arch(arch)}") ldflags.append(f"-arch {_to_apple_arch(arch)}") autotools = Autotools(self) autotools.make(args=[ - f"BUILD_DIR={os.path.join("build", arch)}" + f"BUILD_DIR={os.path.join('build', arch)}", f"ARCH={self._arch_map.get(arch)}", - f"CGO_CFLAGS={cflags}", - f"CGO_LDFLAGS={ldflags}" + f"CGO_CFLAGS={shlex.quote(' '.join(cflags))}", + f"CGO_LDFLAGS={shlex.quote(' '.join(ldflags))}" ]) if is_apple_os(self) and self._is_multiarch: - dir = os.path.join(self.source_folder, "merged") - archives = _filter_files(self.source_folder, "*.a", None, False, dir) - output = os.path.join(dir, Path(archives[0]).name) - - mkdir(dir) + merged_dir = os.path.join(self.source_folder, "merged") + archives = sorted( + str(path) for path in Path(self.source_folder).glob("build/*/*.a") + ) + if not archives: + raise ConanInvalidConfiguration( + f"{self.name} v{self.version} did not produce archives for {self.settings.arch}" + ) + output = os.path.join(merged_dir, Path(archives[0]).name) + + mkdir(self, merged_dir) lipo = XCRun(self).find('lipo') - self.run(f"{lipo} -create -output {output} {archives}") + self.run("{} -create -output {} {}".format( + shlex.quote(lipo), + shlex.quote(output), + " ".join(shlex.quote(archive) for archive in archives) + )) def _rename_header(self): if not self._is_windows: @@ -138,11 +148,12 @@ def _rename_libs(self): os.rename(src, dst) def package(self): - dir_pattern = os.path.join("build", "merged") if self._is_multiarch else os.path.join("build", "*") - copy(self, os.path.join(dir_pattern, "*.h"), src=self.build_folder, dst=os.path.join(self.package_folder, "include"), keep_path=False) - copy(self, os.path.join(dir_pattern, "*.a"), src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) - copy(self, os.path.join(dir_pattern, "*.lib"), src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) - copy(self, os.path.join(dir_pattern, "*.dll"), src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False) + header_src = os.path.join(self.source_folder, "build", self._archs[0]) + lib_src = os.path.join(self.source_folder, "merged") if self._is_multiarch else header_src + copy(self, "*.h", src=header_src, dst=os.path.join(self.package_folder, "include"), keep_path=False) + copy(self, "*.a", src=lib_src, dst=os.path.join(self.package_folder, "lib"), keep_path=False) + copy(self, "*.lib", src=lib_src, dst=os.path.join(self.package_folder, "lib"), keep_path=False) + copy(self, "*.dll", src=lib_src, dst=os.path.join(self.package_folder, "bin"), keep_path=False) self._rename_header() def package_info(self): diff --git a/recipes/awg-go/conanfile.py b/recipes/awg-go/conanfile.py index ac2804533a..27ae370b2e 100644 --- a/recipes/awg-go/conanfile.py +++ b/recipes/awg-go/conanfile.py @@ -2,10 +2,12 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.layout import basic_layout from conan.tools.files import get, copy +from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain from conan.tools.env import VirtualBuildEnv import os +import shlex class AwgGo(ConanFile): @@ -82,7 +84,12 @@ def _build_go_arch(self, goarch): def _build_universal_macos(self): outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] universal_output = os.path.join(self.build_folder, self._binary_name) - self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") + lipo = XCRun(self).find("lipo") + self.run("{} -create {} -output {}".format( + shlex.quote(lipo), + " ".join(shlex.quote(output) for output in outputs), + shlex.quote(universal_output) + )) def layout(self): basic_layout(self, build_folder=".") diff --git a/recipes/tun2socks/conanfile.py b/recipes/tun2socks/conanfile.py index 4df179922f..54481a7e7e 100644 --- a/recipes/tun2socks/conanfile.py +++ b/recipes/tun2socks/conanfile.py @@ -2,10 +2,12 @@ from conan.tools.layout import basic_layout from conan.tools.files import get, copy, chdir from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain from conan.tools.env import VirtualBuildEnv import os +import shlex class Tun2Socks(ConanFile): @@ -79,6 +81,8 @@ def _build_go_arch(self, goarch): output_path = os.path.join(self.build_folder, self._binary_name) if not os.path.exists(output_path): output_path = os.path.join(self.source_folder, self._binary_name) + if not os.path.exists(output_path): + output_path = os.path.join(self.source_folder, "build", self._binary_name) arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") os.rename(output_path, arch_output_path) @@ -87,7 +91,12 @@ def _build_go_arch(self, goarch): def _build_universal_macos(self): outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] universal_output = os.path.join(self.build_folder, self._binary_name) - self.run(f"lipo -create {' '.join(outputs)} -output {universal_output}") + lipo = XCRun(self).find("lipo") + self.run("{} -create {} -output {}".format( + shlex.quote(lipo), + " ".join(shlex.quote(output) for output in outputs), + shlex.quote(universal_output) + )) @property def _is_windows(self): From 6e7925b534c1be159eaaa8430fb569f2ff3e67f6 Mon Sep 17 00:00:00 2001 From: spectrum Date: Tue, 26 May 2026 15:59:39 +0300 Subject: [PATCH 5/9] Sign macOS OpenVPN helper script --- client/CMakeLists.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 2f138157d9..783ed95e05 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -252,6 +252,25 @@ if(OVPN_SCRIPTS) "$" ) + if(APPLE AND NOT IOS AND NOT MACOS_NE) + set(SIGN_OVPN_SCRIPT [=[ +if [ "$CODE_SIGNING_ALLOWED" != "NO" ]; then + identity="$EXPANDED_CODE_SIGN_IDENTITY" + if [ -z "$identity" ]; then + identity="$CODE_SIGN_IDENTITY" + fi + if [ -z "$identity" ]; then + identity="-" + fi + /usr/bin/codesign --force --sign "$identity" "$1" +fi +]=]) + add_custom_command(TARGET ${PROJECT} POST_BUILD + COMMAND /bin/sh -c "${SIGN_OVPN_SCRIPT}" _ "$/update-resolv-conf.sh" + VERBATIM + ) + endif() + install(FILES ${OVPN_SCRIPTS} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT AmneziaVPN From c9befdfaad7a078d8e30d43f8fcebecb3b2463ad Mon Sep 17 00:00:00 2001 From: spectrum Date: Fri, 29 May 2026 13:56:19 +0300 Subject: [PATCH 6/9] Address macOS build review comments --- client/CMakeLists.txt | 40 +++++++++++++++------------------- recipes/awg-go/conanfile.py | 28 ++++++------------------ recipes/tun2socks/conanfile.py | 37 +++++++++++++------------------ 3 files changed, 40 insertions(+), 65 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 783ed95e05..4d72c35749 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -239,35 +239,31 @@ install(SCRIPT ${QT_DEPLOY_SCRIPT} ) if (APPLE AND NOT IOS AND NOT MACOS_NE) - list(APPEND OVPN_SCRIPTS "${CMAKE_SOURCE_DIR}/deploy/data/macos/update-resolv-conf.sh") + set(MACOS_OVPN_SCRIPT "${CMAKE_SOURCE_DIR}/deploy/data/macos/update-resolv-conf.sh") + list(APPEND OVPN_SCRIPTS ${MACOS_OVPN_SCRIPT}) + set_source_files_properties(${MACOS_OVPN_SCRIPT} PROPERTIES + MACOSX_PACKAGE_LOCATION MacOS + ) + target_sources(${PROJECT} PRIVATE ${MACOS_OVPN_SCRIPT}) + if(BUILD_VPN_KEYCHAIN) + set(MACOS_CODE_SIGN_FLAGS "--keychain ${BUILD_VPN_KEYCHAIN} --deep") + else() + set(MACOS_CODE_SIGN_FLAGS "--deep") + endif() + set_target_properties(${PROJECT} PROPERTIES + XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "${MACOS_CODE_SIGN_FLAGS}" + ) endif() if (LINUX AND NOT ANDROID) list(APPEND OVPN_SCRIPTS "${CMAKE_SOURCE_DIR}/deploy/data/linux/update-resolv-conf.sh") endif() if(OVPN_SCRIPTS) - add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${OVPN_SCRIPTS} - "$" - ) - - if(APPLE AND NOT IOS AND NOT MACOS_NE) - set(SIGN_OVPN_SCRIPT [=[ -if [ "$CODE_SIGNING_ALLOWED" != "NO" ]; then - identity="$EXPANDED_CODE_SIGN_IDENTITY" - if [ -z "$identity" ]; then - identity="$CODE_SIGN_IDENTITY" - fi - if [ -z "$identity" ]; then - identity="-" - fi - /usr/bin/codesign --force --sign "$identity" "$1" -fi -]=]) + if(NOT APPLE) add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND /bin/sh -c "${SIGN_OVPN_SCRIPT}" _ "$/update-resolv-conf.sh" - VERBATIM + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${OVPN_SCRIPTS} + "$" ) endif() diff --git a/recipes/awg-go/conanfile.py b/recipes/awg-go/conanfile.py index 27ae370b2e..c427f6ac22 100644 --- a/recipes/awg-go/conanfile.py +++ b/recipes/awg-go/conanfile.py @@ -4,7 +4,6 @@ from conan.tools.files import get, copy from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain -from conan.tools.env import VirtualBuildEnv import os import shlex @@ -50,30 +49,15 @@ def _goarchs(self): def _is_universal_macos(self): return str(self.settings.os) == "Macos" and len(self._archs) > 1 - @property - def _is_unsupported_multi_arch(self): - return len(self._archs) > 1 and not self._is_universal_macos - - def _go_cache_vars(self): - return { - "GOPATH": os.path.join(self.build_folder, "gopath"), - "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), - "GOCACHE": os.path.join(self.build_folder, "gocache"), - "GOTELEMETRY": "off", - } - - def _define_go_cache_env(self, env): - for name, value in self._go_cache_vars().items(): - env.define(name, value) - def _go_arch_make_args(self, goarch): - return [f"{name}={value}" for name, value in self._go_cache_vars().items()] + [ + return [ f"GOOS={self._goos}", f"GOARCH={goarch}", ] def _build_go_arch(self, goarch): autotools = Autotools(self) + autotools.make("clean") autotools.make(args=self._go_arch_make_args(goarch)) output_path = os.path.join(self.build_folder, self._binary_name) @@ -98,7 +82,7 @@ def build_requirements(self): self.tool_requires("go/1.26.0") def validate(self): - if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: + if not self._goos or not all(self._goarchs) or (len(self._archs) > 1 and not self._is_universal_macos): raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) @@ -109,10 +93,12 @@ def source(self): ) def generate(self): - VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) env = tc.environment() - self._define_go_cache_env(env) + env.define("GOPATH", os.path.join(self.build_folder, "gopath")) + env.define("GOMODCACHE", os.path.join(self.build_folder, "gopath", "pkg", "mod")) + env.define("GOCACHE", os.path.join(self.build_folder, "gocache")) + env.define("GOTELEMETRY", "off") env.define("GOOS", self._goos) if not self._is_universal_macos: env.define("GOARCH", self._goarch) diff --git a/recipes/tun2socks/conanfile.py b/recipes/tun2socks/conanfile.py index 54481a7e7e..8205d1fdbd 100644 --- a/recipes/tun2socks/conanfile.py +++ b/recipes/tun2socks/conanfile.py @@ -4,7 +4,6 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain -from conan.tools.env import VirtualBuildEnv import os import shlex @@ -50,32 +49,24 @@ def _goarchs(self): def _is_universal_macos(self): return str(self.settings.os) == "Macos" and len(self._archs) > 1 - @property - def _is_unsupported_multi_arch(self): - return len(self._archs) > 1 and not self._is_universal_macos - - def _go_cache_vars(self): - return { - "GOPATH": os.path.join(self.build_folder, "gopath"), - "GOMODCACHE": os.path.join(self.build_folder, "gopath", "pkg", "mod"), - "GOCACHE": os.path.join(self.build_folder, "gocache"), - "GOTELEMETRY": "off", - } - - def _define_go_cache_env(self, env): - for name, value in self._go_cache_vars().items(): - env.define(name, value) - def _go_arch_make_args(self, goarch): - return [f"{name}={value}" for name, value in self._go_cache_vars().items()] + [ + return [ "LDFLAGS=", f"GOOS={self._goos}", f"GOARCH={goarch}", ] def _build_go_arch(self, goarch): + autotools = Autotools(self) + for output_path in ( + os.path.join(self.build_folder, self._binary_name), + os.path.join(self.source_folder, self._binary_name), + os.path.join(self.source_folder, "build", self._binary_name), + ): + if os.path.exists(output_path): + os.remove(output_path) + with chdir(self, self.source_folder): - autotools = Autotools(self) autotools.make(self._binary_name, args=self._go_arch_make_args(goarch)) output_path = os.path.join(self.build_folder, self._binary_name) @@ -110,7 +101,7 @@ def layout(self): basic_layout(self) def validate(self): - if not self._goos or not all(self._goarchs) or self._is_unsupported_multi_arch: + if not self._goos or not all(self._goarchs) or (len(self._archs) > 1 and not self._is_universal_macos): raise ConanInvalidConfiguration( f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}" ) @@ -133,10 +124,12 @@ def source(self): ) def generate(self): - VirtualBuildEnv(self).generate() tc = AutotoolsToolchain(self) env = tc.environment() - self._define_go_cache_env(env) + env.define("GOPATH", os.path.join(self.build_folder, "gopath")) + env.define("GOMODCACHE", os.path.join(self.build_folder, "gopath", "pkg", "mod")) + env.define("GOCACHE", os.path.join(self.build_folder, "gocache")) + env.define("GOTELEMETRY", "off") env.define("LDFLAGS", "") env.define("CGO_LDFLAGS", tc.ldflags) env.define("CGO_CFLAGS", tc.cflags) From 9b8b71647920e726714d7e803625b93123003015 Mon Sep 17 00:00:00 2001 From: spectrum Date: Fri, 29 May 2026 15:31:39 +0300 Subject: [PATCH 7/9] Isolate awg-go universal builds --- recipes/awg-go/conanfile.py | 64 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/recipes/awg-go/conanfile.py b/recipes/awg-go/conanfile.py index c427f6ac22..6d3dcd1d54 100644 --- a/recipes/awg-go/conanfile.py +++ b/recipes/awg-go/conanfile.py @@ -1,7 +1,7 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.layout import basic_layout -from conan.tools.files import get, copy +from conan.tools.files import get, copy, chdir, rmdir from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain @@ -49,32 +49,6 @@ def _goarchs(self): def _is_universal_macos(self): return str(self.settings.os) == "Macos" and len(self._archs) > 1 - def _go_arch_make_args(self, goarch): - return [ - f"GOOS={self._goos}", - f"GOARCH={goarch}", - ] - - def _build_go_arch(self, goarch): - autotools = Autotools(self) - autotools.make("clean") - autotools.make(args=self._go_arch_make_args(goarch)) - - output_path = os.path.join(self.build_folder, self._binary_name) - arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") - os.rename(output_path, arch_output_path) - return arch_output_path - - def _build_universal_macos(self): - outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] - universal_output = os.path.join(self.build_folder, self._binary_name) - lipo = XCRun(self).find("lipo") - self.run("{} -create {} -output {}".format( - shlex.quote(lipo), - " ".join(shlex.quote(output) for output in outputs), - shlex.quote(universal_output) - )) - def layout(self): basic_layout(self, build_folder=".") @@ -108,7 +82,41 @@ def generate(self): def build(self): if self._is_universal_macos: - self._build_universal_macos() + outputs = [] + for goarch in self._goarchs: + arch_build_folder = os.path.join(self.build_folder, f"build-{goarch}") + rmdir(self, arch_build_folder) + copy(self, "*", src=self.source_folder, dst=arch_build_folder, excludes=( + "amneziawg-go", + "amneziawg-go-*", + "build-*", + "conan", + "conan/*", + "gocache", + "gocache/*", + "gopath", + "gopath/*", + )) + + at = Autotools(self) + with chdir(self, arch_build_folder): + at.make(args=[ + f"GOOS={self._goos}", + f"GOARCH={goarch}", + ]) + + output_path = os.path.join(arch_build_folder, self._binary_name) + arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") + os.rename(output_path, arch_output_path) + outputs.append(arch_output_path) + + universal_output = os.path.join(self.build_folder, self._binary_name) + lipo = XCRun(self).find("lipo") + self.run("{} -create {} -output {}".format( + shlex.quote(lipo), + " ".join(shlex.quote(output) for output in outputs), + shlex.quote(universal_output) + )) return at = Autotools(self) From 0a85137d37e8b2671747b0d132dfb2c5ac1a0edf Mon Sep 17 00:00:00 2001 From: spectrum Date: Fri, 29 May 2026 16:31:11 +0300 Subject: [PATCH 8/9] Disable Xcode signing for non-NE macOS --- client/CMakeLists.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 4d72c35749..802ca29448 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -245,13 +245,9 @@ if (APPLE AND NOT IOS AND NOT MACOS_NE) MACOSX_PACKAGE_LOCATION MacOS ) target_sources(${PROJECT} PRIVATE ${MACOS_OVPN_SCRIPT}) - if(BUILD_VPN_KEYCHAIN) - set(MACOS_CODE_SIGN_FLAGS "--keychain ${BUILD_VPN_KEYCHAIN} --deep") - else() - set(MACOS_CODE_SIGN_FLAGS "--deep") - endif() set_target_properties(${PROJECT} PROPERTIES - XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "${MACOS_CODE_SIGN_FLAGS}" + XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO" + XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" ) endif() if (LINUX AND NOT ANDROID) From 07b43df2bfbb59a58acdb1ffa2c220f1da7d44d1 Mon Sep 17 00:00:00 2001 From: spectrum Date: Fri, 29 May 2026 18:34:22 +0300 Subject: [PATCH 9/9] Address remaining macOS recipe review comments --- client/CMakeLists.txt | 19 +++----- recipes/awg-go/conanfile.py | 45 ++++++------------ recipes/tun2socks/conanfile.py | 84 ++++++++++------------------------ 3 files changed, 46 insertions(+), 102 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 802ca29448..bac174dbd4 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -239,12 +239,7 @@ install(SCRIPT ${QT_DEPLOY_SCRIPT} ) if (APPLE AND NOT IOS AND NOT MACOS_NE) - set(MACOS_OVPN_SCRIPT "${CMAKE_SOURCE_DIR}/deploy/data/macos/update-resolv-conf.sh") - list(APPEND OVPN_SCRIPTS ${MACOS_OVPN_SCRIPT}) - set_source_files_properties(${MACOS_OVPN_SCRIPT} PROPERTIES - MACOSX_PACKAGE_LOCATION MacOS - ) - target_sources(${PROJECT} PRIVATE ${MACOS_OVPN_SCRIPT}) + list(APPEND OVPN_SCRIPTS "${CMAKE_SOURCE_DIR}/deploy/data/macos/update-resolv-conf.sh") set_target_properties(${PROJECT} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO" XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" @@ -255,13 +250,11 @@ if (LINUX AND NOT ANDROID) endif() if(OVPN_SCRIPTS) - if(NOT APPLE) - add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${OVPN_SCRIPTS} - "$" - ) - endif() + add_custom_command(TARGET ${PROJECT} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${OVPN_SCRIPTS} + "$" + ) install(FILES ${OVPN_SCRIPTS} DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/recipes/awg-go/conanfile.py b/recipes/awg-go/conanfile.py index 6d3dcd1d54..93fa075120 100644 --- a/recipes/awg-go/conanfile.py +++ b/recipes/awg-go/conanfile.py @@ -1,7 +1,7 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.layout import basic_layout -from conan.tools.files import get, copy, chdir, rmdir +from conan.tools.files import get, copy, chdir from conan.tools.apple import XCRun from conan.tools.gnu import Autotools, AutotoolsToolchain @@ -74,53 +74,38 @@ def generate(self): env.define("GOCACHE", os.path.join(self.build_folder, "gocache")) env.define("GOTELEMETRY", "off") env.define("GOOS", self._goos) - if not self._is_universal_macos: - env.define("GOARCH", self._goarch) env.define("CGO_LDFLAGS", tc.ldflags) env.define("CGO_CFLAGS", tc.cflags) tc.generate(env) def build(self): - if self._is_universal_macos: - outputs = [] + outputs = [] + with chdir(self, self.source_folder): for goarch in self._goarchs: - arch_build_folder = os.path.join(self.build_folder, f"build-{goarch}") - rmdir(self, arch_build_folder) - copy(self, "*", src=self.source_folder, dst=arch_build_folder, excludes=( - "amneziawg-go", - "amneziawg-go-*", - "build-*", - "conan", - "conan/*", - "gocache", - "gocache/*", - "gopath", - "gopath/*", - )) - + arch_destdir = os.path.join(self.build_folder, f"build-{goarch}") at = Autotools(self) - with chdir(self, arch_build_folder): - at.make(args=[ - f"GOOS={self._goos}", - f"GOARCH={goarch}", - ]) - - output_path = os.path.join(arch_build_folder, self._binary_name) + at.make("clean") + at.make("install", args=[ + f"DESTDIR={shlex.quote(arch_destdir)}", + "BINDIR=", + f"GOARCH={goarch}", + ]) + output_path = os.path.join(arch_destdir, self._binary_name) arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") os.rename(output_path, arch_output_path) outputs.append(arch_output_path) - universal_output = os.path.join(self.build_folder, self._binary_name) + output = os.path.join(self.build_folder, self._binary_name) + if self._is_universal_macos: lipo = XCRun(self).find("lipo") self.run("{} -create {} -output {}".format( shlex.quote(lipo), " ".join(shlex.quote(output) for output in outputs), - shlex.quote(universal_output) + shlex.quote(output) )) return - at = Autotools(self) - at.make() + os.rename(outputs[0], output) def package(self): copy(self, self._binary_name, src=self.build_folder, dst=self.package_folder) diff --git a/recipes/tun2socks/conanfile.py b/recipes/tun2socks/conanfile.py index 8205d1fdbd..97d0853022 100644 --- a/recipes/tun2socks/conanfile.py +++ b/recipes/tun2socks/conanfile.py @@ -15,6 +15,11 @@ class Tun2Socks(ConanFile): package_type = "application" settings = "os", "arch" _binary_name = "tun2socks" + _arch_map = { + "x86": "386", + "x86_64": "amd64", + "armv8": "arm64" + } @property def _goos(self): @@ -24,23 +29,10 @@ def _goos(self): "Windows": "windows" }.get(str(self.settings.os)) - @property - def _arch_map(self): - return { - "x86": "386", - "x86_64": "amd64", - "armv8": "arm64" - } - @property def _archs(self): return str(self.settings.arch).split("|") - @property - def _goarch(self): - goarchs = [self._arch_map.get(arch) for arch in self._archs] - return goarchs[0] if len(goarchs) == 1 else None - @property def _goarchs(self): return [self._arch_map.get(arch) for arch in self._archs] @@ -49,46 +41,6 @@ def _goarchs(self): def _is_universal_macos(self): return str(self.settings.os) == "Macos" and len(self._archs) > 1 - def _go_arch_make_args(self, goarch): - return [ - "LDFLAGS=", - f"GOOS={self._goos}", - f"GOARCH={goarch}", - ] - - def _build_go_arch(self, goarch): - autotools = Autotools(self) - for output_path in ( - os.path.join(self.build_folder, self._binary_name), - os.path.join(self.source_folder, self._binary_name), - os.path.join(self.source_folder, "build", self._binary_name), - ): - if os.path.exists(output_path): - os.remove(output_path) - - with chdir(self, self.source_folder): - autotools.make(self._binary_name, args=self._go_arch_make_args(goarch)) - - output_path = os.path.join(self.build_folder, self._binary_name) - if not os.path.exists(output_path): - output_path = os.path.join(self.source_folder, self._binary_name) - if not os.path.exists(output_path): - output_path = os.path.join(self.source_folder, "build", self._binary_name) - - arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") - os.rename(output_path, arch_output_path) - return arch_output_path - - def _build_universal_macos(self): - outputs = [self._build_go_arch(goarch) for goarch in self._goarchs] - universal_output = os.path.join(self.build_folder, self._binary_name) - lipo = XCRun(self).find("lipo") - self.run("{} -create {} -output {}".format( - shlex.quote(lipo), - " ".join(shlex.quote(output) for output in outputs), - shlex.quote(universal_output) - )) - @property def _is_windows(self): return str(self.settings.get_safe("os")).startswith("Windows") @@ -134,18 +86,32 @@ def generate(self): env.define("CGO_LDFLAGS", tc.ldflags) env.define("CGO_CFLAGS", tc.cflags) env.define("GOOS", self._goos) - if not self._is_universal_macos: - env.define("GOARCH", self._goarch) tc.generate(env) def build(self): + outputs = [] + with chdir(self, self.source_folder): + for goarch in self._goarchs: + target = f"{self._goos}-{goarch}" + at = Autotools(self) + at.make(target) + output_ext = ".exe" if self._goos == "windows" else "" + output_path = os.path.join(self.source_folder, "build", f"{self._binary_name}-{target}{output_ext}") + arch_output_path = os.path.join(self.build_folder, f"{self._binary_name}-{goarch}") + os.rename(output_path, arch_output_path) + outputs.append(arch_output_path) + + output = os.path.join(self.build_folder, self._binary_name) if self._is_universal_macos: - self._build_universal_macos() + lipo = XCRun(self).find("lipo") + self.run("{} -create {} -output {}".format( + shlex.quote(lipo), + " ".join(shlex.quote(output) for output in outputs), + shlex.quote(output) + )) return - with chdir(self, self.source_folder): - at = Autotools(self) - at.make(self._binary_name) + os.rename(outputs[0], output) def package(self): copy(self, self._binary_name, src=self.build_folder, dst=self.package_folder)