From 088059588c98c13303075344c94a0945fb5fcdc7 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 20 Jul 2023 23:15:49 +0300 Subject: [PATCH 01/11] gn: migrate to Conan v2 --- recipes/gn/all/conanfile.py | 157 +++++++++---------- recipes/gn/all/test_package/conanfile.py | 69 +++----- recipes/gn/all/test_package/test_package.cpp | 2 +- recipes/gn/all/test_v1_package/conanfile.py | 69 ++++++++ 4 files changed, 171 insertions(+), 126 deletions(-) create mode 100644 recipes/gn/all/test_v1_package/conanfile.py diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 14fc7169fc53f..3ca40afd34271 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -1,28 +1,37 @@ -from conans import ConanFile, tools -from conans.errors import ConanInvalidConfiguration -from contextlib import contextmanager -import conan.tools.files as tools_files -import conan.tools.scm as tools_scm import os import sys import textwrap import time -required_conan_version = ">=1.46.0" +import conan.tools.scm as tools_scm +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os +from conan.tools.build import check_min_cppstd +from conan.tools.env import VirtualBuildEnv +from conan.tools.files import chdir, copy, get, load, save +from conan.tools.layout import basic_layout +from conan.tools.microsoft import is_msvc + +required_conan_version = ">=1.47.0" class GnConan(ConanFile): name = "gn" description = "GN is a meta-build system that generates build files for Ninja." - url = "https://github.com/conan-io/conan-center-index" - topics = ("gn", "build", "system", "ninja") license = "BSD-3-Clause" + url = "https://github.com/conan-io/conan-center-index" homepage = "https://gn.googlesource.com/" + topics = ("build system", "ninja") + + package_type = "application" settings = "os", "arch", "compiler", "build_type" - @property - def _source_subfolder(self): - return "source_subfolder" + def layout(self): + basic_layout(self, src_folder="src") + + def package_id(self): + del self.info.settings.compiler @property def _minimum_compiler_version_supporting_cxx17(self): @@ -35,94 +44,80 @@ def _minimum_compiler_version_supporting_cxx17(self): def validate(self): if self.settings.compiler.cppstd: - tools.check_min_cppstd(self, 17) + check_min_cppstd(self, 17) else: if self._minimum_compiler_version_supporting_cxx17: - if tools_scm.Version(self.settings.compiler.version) < self._minimum_compiler_version_supporting_cxx17: + if ( + tools_scm.Version(self.settings.compiler.version) + < self._minimum_compiler_version_supporting_cxx17 + ): raise ConanInvalidConfiguration("gn requires a compiler supporting c++17") else: - self.output.warn("gn recipe does not recognize the compiler. gn requires a compiler supporting c++17. Assuming it does.") - - def package_id(self): - del self.info.settings.compiler - - def source(self): - tools_files.get(self, **self.conan_data["sources"][self.version], destination=self._source_subfolder) + self.output.warning( + "gn recipe does not recognize the compiler. gn requires a compiler supporting c++17." + " Assuming it does." + ) def build_requirements(self): # FIXME: add cpython build requirements for `build/gen.py`. self.build_requires("ninja/1.10.2") - @contextmanager - def _build_context(self): - if self.settings.compiler == "Visual Studio": - with tools.vcvars(self.settings): - yield - else: - compiler_defaults = {} - if self.settings.compiler == "gcc": - compiler_defaults = { - "CC": "gcc", - "CXX": "g++", - "AR": "ar", - "LD": "g++", - } - elif self.settings.compiler == "clang": - compiler_defaults = { - "CC": "clang", - "CXX": "clang++", - "AR": "ar", - "LD": "clang++", - } - env = {} - for k in ("CC", "CXX", "AR", "LD"): - v = tools.get_env(k, compiler_defaults.get(k, None)) - if v: - env[k] = v - with tools.environment_append(env): - yield - - @staticmethod - def _to_gn_platform(os_, compiler): - if tools.is_apple_os(os_): + def source(self): + get(self, **self.conan_data["sources"][self.version]) + + def _to_gn_platform(self, os_, compiler): + if is_apple_os(self): return "darwin" - if compiler == "Visual Studio": + if is_msvc(self): return "msvc" # Assume gn knows about the os return str(os_).lower() + def generate(self): + env = VirtualBuildEnv(self) + env.generate() + configure_args = [ + "--no-last-commit-position", + "--host={}".format(self._to_gn_platform(self.settings.os, self.settings.compiler)), + ] + if self.settings.build_type in ["Debug", "RelWithDebInfo"]: + configure_args.append("-d") + save(self, os.path.join(self.source_folder, "configure_args"), " ".join(configure_args)) + def build(self): - with tools.chdir(self._source_subfolder): - with self._build_context(): - # Generate dummy header to be able to run `build/ben.py` with `--no-last-commit-position`. This allows running the script without the tree having to be a git checkout. - tools.save(os.path.join("src", "gn", "last_commit_position.h"), - textwrap.dedent("""\ - #pragma once - #define LAST_COMMIT_POSITION "1" - #define LAST_COMMIT_POSITION_NUM 1 - """)) - conf_args = [ - "--no-last-commit-position", - "--host={}".format(self._to_gn_platform(self.settings.os, self.settings.compiler)), - ] - if self.settings.build_type == "Debug": - conf_args.append("-d") - self.run("{} build/gen.py {}".format(sys.executable, " ".join(conf_args)), run_environment=True) - # Try sleeping one second to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) - time.sleep(1) - build_args = [ - "-C", "out", - "-j{}".format(tools.cpu_count()), - ] - self.run("ninja {}".format(" ".join(build_args)), run_environment=True) + with chdir(self, self.source_folder): + # Generate dummy header to be able to run `build/ben.py` with `--no-last-commit-position`. This allows running the script without the tree having to be a git checkout. + save( + self, + os.path.join("src", "gn", "last_commit_position.h"), + textwrap.dedent("""\ + #pragma once + #define LAST_COMMIT_POSITION "1" + #define LAST_COMMIT_POSITION_NUM 1 + """), + ) + self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) + # Try sleeping one second to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) + time.sleep(1) + build_args = ["-C", "out", f"-j{os.cpu_count()}"] + self.run("ninja " + " ".join(build_args)) def package(self): - self.copy("LICENSE", src=self._source_subfolder, dst="licenses") - self.copy("gn", src=os.path.join(self._source_subfolder, "out"), dst="bin") - self.copy("gn.exe", src=os.path.join(self._source_subfolder, "out"), dst="bin") + copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) + copy(self, "gn", + src=os.path.join(self.source_folder, "out"), + dst=os.path.join(self.package_folder, "bin")) + copy(self, + "gn.exe", + src=os.path.join(self.source_folder, "out"), + dst=os.path.join(self.package_folder, "bin")) def package_info(self): + self.cpp_info.includedirs = [] + self.cpp_info.frameworkdirs = [] + self.cpp_info.libdirs = [] + self.cpp_info.resdirs = [] + bin_path = os.path.join(self.package_folder, "bin") - self.output.info("Appending PATH environment variable: {}".format(bin_path)) + self.output.info(f"Appending PATH environment variable: {bin_path}") self.env_info.PATH.append(bin_path) - self.cpp_info.includedirs = [] diff --git a/recipes/gn/all/test_package/conanfile.py b/recipes/gn/all/test_package/conanfile.py index 6afe525facbbe..0077eae5eda1d 100644 --- a/recipes/gn/all/test_package/conanfile.py +++ b/recipes/gn/all/test_package/conanfile.py @@ -1,46 +1,27 @@ -from conans import ConanFile, CMake, tools -from contextlib import contextmanager import os +from conan import ConanFile +from conan.tools.apple import is_apple_os +from conan.tools.build import can_run, cross_building +from conan.tools.layout import basic_layout +from conan.tools.microsoft import unix_path + class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" + settings = "os", "arch", "compiler", "build_type" + generators = "VirtualRunEnv" + test_type = "explicit" def build_requirements(self): - self.build_requires("ninja/1.10.2") + self.tool_requires(self.tested_reference_str) + self.tool_requires("ninja/1.11.1") - @contextmanager - def _build_context(self): - if self.settings.compiler == "Visual Studio": - with tools.vcvars(self.settings): - yield - else: - compiler_defaults = {} - if self.settings.compiler == "gcc": - compiler_defaults = { - "CC": "gcc", - "CXX": "g++", - "AR": "ar", - "LD": "g++", - } - elif self.settings.compiler in ("apple-clang", "clang"): - compiler_defaults = { - "CC": "clang", - "CXX": "clang++", - "AR": "ar", - "LD": "clang++", - } - env = {} - for k in ("CC", "CXX", "AR", "LD"): - v = tools.get_env(k, compiler_defaults.get(k, None)) - if v: - env[k] = v - with tools.environment_append(env): - yield + def layout(self): + basic_layout(self) @property def _target_os(self): - if tools.is_apple_os(self.settings.os): + if is_apple_os(self): return "mac" # Assume gn knows about the os return { @@ -54,16 +35,16 @@ def _target_cpu(self): }.get(str(self.settings.arch), str(self.settings.arch)) def build(self): - if not tools.cross_building(self.settings): - with tools.chdir(self.source_folder): - gn_args = [ - os.path.relpath(os.path.join(self.build_folder, "bin"), os.getcwd()).replace("\\", "/"), - "--args=\"target_os=\\\"{os_}\\\" target_cpu=\\\"{cpu}\\\"\"".format(os_=self._target_os, cpu=self._target_cpu), - ] - self.run("gn gen {}".format(" ".join(gn_args)), run_environment=True) - with self._build_context(): - self.run("ninja -v -j{} -C bin".format(tools.cpu_count()), run_environment=True) + if not cross_building(self): + rel_bindir = unix_path(self, os.path.relpath(os.path.join(self.cpp.build.bindir), os.getcwd())) + gn_args = [ + rel_bindir, + f'--args="target_os=\\"{self._target_os}\\" target_cpu=\\"{self._target_cpu}\\""', + ] + self.run("gn gen " + " ".join(gn_args)) + self.run(f"ninja -v -j{os.cpu_count()} -C {rel_bindir}") def test(self): - if not tools.cross_building(self.settings): - self.run(os.path.join("bin", "test_package"), run_environment=True) + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/gn/all/test_package/test_package.cpp b/recipes/gn/all/test_package/test_package.cpp index 576931dcb63ac..7a70c493ae50a 100644 --- a/recipes/gn/all/test_package/test_package.cpp +++ b/recipes/gn/all/test_package/test_package.cpp @@ -3,7 +3,7 @@ #include -int main(int argc, char* argv[]) { +int main() { std::cout << get_test_shared_text() << "\n"; std::cout << get_test_static_text() << "\n"; return 0; diff --git a/recipes/gn/all/test_v1_package/conanfile.py b/recipes/gn/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..6afe525facbbe --- /dev/null +++ b/recipes/gn/all/test_v1_package/conanfile.py @@ -0,0 +1,69 @@ +from conans import ConanFile, CMake, tools +from contextlib import contextmanager +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + + def build_requirements(self): + self.build_requires("ninja/1.10.2") + + @contextmanager + def _build_context(self): + if self.settings.compiler == "Visual Studio": + with tools.vcvars(self.settings): + yield + else: + compiler_defaults = {} + if self.settings.compiler == "gcc": + compiler_defaults = { + "CC": "gcc", + "CXX": "g++", + "AR": "ar", + "LD": "g++", + } + elif self.settings.compiler in ("apple-clang", "clang"): + compiler_defaults = { + "CC": "clang", + "CXX": "clang++", + "AR": "ar", + "LD": "clang++", + } + env = {} + for k in ("CC", "CXX", "AR", "LD"): + v = tools.get_env(k, compiler_defaults.get(k, None)) + if v: + env[k] = v + with tools.environment_append(env): + yield + + @property + def _target_os(self): + if tools.is_apple_os(self.settings.os): + return "mac" + # Assume gn knows about the os + return { + "Windows": "win", + }.get(str(self.settings.os), str(self.settings.os).lower()) + + @property + def _target_cpu(self): + return { + "x86_64": "x64", + }.get(str(self.settings.arch), str(self.settings.arch)) + + def build(self): + if not tools.cross_building(self.settings): + with tools.chdir(self.source_folder): + gn_args = [ + os.path.relpath(os.path.join(self.build_folder, "bin"), os.getcwd()).replace("\\", "/"), + "--args=\"target_os=\\\"{os_}\\\" target_cpu=\\\"{cpu}\\\"\"".format(os_=self._target_os, cpu=self._target_cpu), + ] + self.run("gn gen {}".format(" ".join(gn_args)), run_environment=True) + with self._build_context(): + self.run("ninja -v -j{} -C bin".format(tools.cpu_count()), run_environment=True) + + def test(self): + if not tools.cross_building(self.settings): + self.run(os.path.join("bin", "test_package"), run_environment=True) From b070eb62a152fc22b369a6b949b8196624a582bc Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Wed, 2 Aug 2023 00:47:34 +0300 Subject: [PATCH 02/11] gn: fix MSVC build --- recipes/gn/all/conanfile.py | 40 ++++++++++++++---------- recipes/gn/all/test_package/conanfile.py | 2 +- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 3ca40afd34271..7609ca88d864a 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -3,7 +3,6 @@ import textwrap import time -import conan.tools.scm as tools_scm from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.apple import is_apple_os @@ -11,7 +10,8 @@ from conan.tools.env import VirtualBuildEnv from conan.tools.files import chdir, copy, get, load, save from conan.tools.layout import basic_layout -from conan.tools.microsoft import is_msvc +from conan.tools.microsoft import is_msvc, VCVars +from conan.tools.scm import Version required_conan_version = ">=1.47.0" @@ -37,6 +37,7 @@ def package_id(self): def _minimum_compiler_version_supporting_cxx17(self): return { "Visual Studio": 15, + "msvc": 191, "gcc": 7, "clang": 4, "apple-clang": 10, @@ -47,10 +48,7 @@ def validate(self): check_min_cppstd(self, 17) else: if self._minimum_compiler_version_supporting_cxx17: - if ( - tools_scm.Version(self.settings.compiler.version) - < self._minimum_compiler_version_supporting_cxx17 - ): + if Version(self.settings.compiler.version) < self._minimum_compiler_version_supporting_cxx17: raise ConanInvalidConfiguration("gn requires a compiler supporting c++17") else: self.output.warning( @@ -60,25 +58,31 @@ def validate(self): def build_requirements(self): # FIXME: add cpython build requirements for `build/gen.py`. - self.build_requires("ninja/1.10.2") + self.build_requires("ninja/1.11.1") def source(self): get(self, **self.conan_data["sources"][self.version]) - def _to_gn_platform(self, os_, compiler): + @property + def _gn_platform(self): if is_apple_os(self): return "darwin" if is_msvc(self): return "msvc" # Assume gn knows about the os - return str(os_).lower() + return str(self.settings.os).lower() def generate(self): env = VirtualBuildEnv(self) env.generate() + + if is_msvc(self): + vcvars = VCVars(self) + vcvars.generate() + configure_args = [ "--no-last-commit-position", - "--host={}".format(self._to_gn_platform(self.settings.os, self.settings.compiler)), + f"--host={self._gn_platform}", ] if self.settings.build_type in ["Debug", "RelWithDebInfo"]: configure_args.append("-d") @@ -104,13 +108,15 @@ def build(self): def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) - copy(self, "gn", - src=os.path.join(self.source_folder, "out"), - dst=os.path.join(self.package_folder, "bin")) - copy(self, - "gn.exe", - src=os.path.join(self.source_folder, "out"), - dst=os.path.join(self.package_folder, "bin")) + if self.settings.os == "Windows": + copy(self, + "gn.exe", + src=os.path.join(self.source_folder, "out"), + dst=os.path.join(self.package_folder, "bin")) + else: + copy(self, "gn", + src=os.path.join(self.source_folder, "out"), + dst=os.path.join(self.package_folder, "bin")) def package_info(self): self.cpp_info.includedirs = [] diff --git a/recipes/gn/all/test_package/conanfile.py b/recipes/gn/all/test_package/conanfile.py index 0077eae5eda1d..734e9293c87bd 100644 --- a/recipes/gn/all/test_package/conanfile.py +++ b/recipes/gn/all/test_package/conanfile.py @@ -9,7 +9,7 @@ class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" - generators = "VirtualRunEnv" + generators = "VirtualRunEnv", "VCVars" test_type = "explicit" def build_requirements(self): From 71326c4065cbb13552b3373b5e7561451399a529 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Mon, 16 Oct 2023 14:34:16 +0300 Subject: [PATCH 03/11] gn: fix test_v1_package --- recipes/gn/all/test_v1_package/conanfile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/recipes/gn/all/test_v1_package/conanfile.py b/recipes/gn/all/test_v1_package/conanfile.py index 6afe525facbbe..16b457e153391 100644 --- a/recipes/gn/all/test_v1_package/conanfile.py +++ b/recipes/gn/all/test_v1_package/conanfile.py @@ -55,14 +55,14 @@ def _target_cpu(self): def build(self): if not tools.cross_building(self.settings): - with tools.chdir(self.source_folder): + with tools.chdir(os.path.join(self.source_folder, os.pardir, "test_package")): gn_args = [ os.path.relpath(os.path.join(self.build_folder, "bin"), os.getcwd()).replace("\\", "/"), - "--args=\"target_os=\\\"{os_}\\\" target_cpu=\\\"{cpu}\\\"\"".format(os_=self._target_os, cpu=self._target_cpu), + '--args="target_os=\\"{os_}\\" target_cpu=\\"{cpu}\\""'.format(os_=self._target_os, cpu=self._target_cpu), ] - self.run("gn gen {}".format(" ".join(gn_args)), run_environment=True) + self.run(f"gn gen {' '.join(gn_args)}", run_environment=True) with self._build_context(): - self.run("ninja -v -j{} -C bin".format(tools.cpu_count()), run_environment=True) + self.run(f"ninja -v -j{tools.cpu_count()} -C bin", run_environment=True) def test(self): if not tools.cross_building(self.settings): From c2f315beadce4a921d1c7b300c46dd9b3291e0b6 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Tue, 17 Oct 2023 11:52:03 +0300 Subject: [PATCH 04/11] gn: avoid git commit parsing in gen.py --- recipes/gn/all/conanfile.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 7609ca88d864a..2a065bca8ef52 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -8,7 +8,7 @@ from conan.tools.apple import is_apple_os from conan.tools.build import check_min_cppstd from conan.tools.env import VirtualBuildEnv -from conan.tools.files import chdir, copy, get, load, save +from conan.tools.files import chdir, copy, get, load, save, replace_in_file from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, VCVars from conan.tools.scm import Version @@ -90,16 +90,19 @@ def generate(self): def build(self): with chdir(self, self.source_folder): - # Generate dummy header to be able to run `build/ben.py` with `--no-last-commit-position`. This allows running the script without the tree having to be a git checkout. - save( - self, - os.path.join("src", "gn", "last_commit_position.h"), + # Generate dummy header to be able to run `build/gen.py` with `--no-last-commit-position`. + # This allows running the script without the tree having to be a git checkout. + save(self, os.path.join(self.source_folder, "src", "gn", "last_commit_position.h"), textwrap.dedent("""\ #pragma once #define LAST_COMMIT_POSITION "1" #define LAST_COMMIT_POSITION_NUM 1 """), ) + # Disable GenerateLastCommitPosition() + replace_in_file(self, os.path.join(self.source_folder, "build/gen.py"), + "def GenerateLastCommitPosition(host, header):", + "def GenerateLastCommitPosition(host, header):\n return") self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) # Try sleeping one second to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) time.sleep(1) From 6b5b830fb4403bedd076edd457132aad25a0845b Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Tue, 17 Oct 2023 11:59:17 +0300 Subject: [PATCH 05/11] gn: make sure CXX env var is set --- recipes/gn/all/conanfile.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 2a065bca8ef52..7a80e28b3193d 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -7,7 +7,7 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.apple import is_apple_os from conan.tools.build import check_min_cppstd -from conan.tools.env import VirtualBuildEnv +from conan.tools.env import VirtualBuildEnv, Environment from conan.tools.files import chdir, copy, get, load, save, replace_in_file from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, VCVars @@ -73,8 +73,15 @@ def _gn_platform(self): return str(self.settings.os).lower() def generate(self): + # Make sure CXX env var is set, otherwise gn defaults it to clang++ + # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 env = VirtualBuildEnv(self) + compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) + cxx = compilers_by_conf.get("cpp") or env.vars().get("CXX") env.generate() + env = Environment() + env.define("CXX", cxx) + env.vars(self).save_script("conanbuild_ninja") if is_msvc(self): vcvars = VCVars(self) From 25b5d904d6bf73ab5e498a9f71670f0ca13afe49 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Tue, 17 Oct 2023 16:39:21 +0300 Subject: [PATCH 06/11] gn: move CXX setting to build() --- recipes/gn/all/conanfile.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 7a80e28b3193d..debee0dc609b8 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -73,15 +73,8 @@ def _gn_platform(self): return str(self.settings.os).lower() def generate(self): - # Make sure CXX env var is set, otherwise gn defaults it to clang++ - # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 env = VirtualBuildEnv(self) - compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) - cxx = compilers_by_conf.get("cpp") or env.vars().get("CXX") env.generate() - env = Environment() - env.define("CXX", cxx) - env.vars(self).save_script("conanbuild_ninja") if is_msvc(self): vcvars = VCVars(self) @@ -106,13 +99,22 @@ def build(self): #define LAST_COMMIT_POSITION_NUM 1 """), ) + # Disable GenerateLastCommitPosition() replace_in_file(self, os.path.join(self.source_folder, "build/gen.py"), "def GenerateLastCommitPosition(host, header):", "def GenerateLastCommitPosition(host, header):\n return") + + # Make sure CXX env var is set, otherwise gn defaults it to clang++ + # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 + compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) + os.environ["CXX"] = compilers_by_conf.get("cpp") or VirtualBuildEnv(self).vars().get("CXX") + self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) + # Try sleeping one second to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) time.sleep(1) + build_args = ["-C", "out", f"-j{os.cpu_count()}"] self.run("ninja " + " ".join(build_args)) From 498678874c85183437ade8c3a5ab67604422920a Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Fri, 3 Nov 2023 17:18:25 +0200 Subject: [PATCH 07/11] gn: try to fix ninja issue on macOS [1/1] Regenerating ninja files manifest 'build.ninja' still dirty after 100 tries, perhaps system time is not set --- recipes/gn/all/conanfile.py | 47 +++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index debee0dc609b8..9ad7141c2eb5d 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -1,13 +1,14 @@ import os +import shutil import sys import textwrap import time from conan import ConanFile from conan.errors import ConanInvalidConfiguration -from conan.tools.apple import is_apple_os +from conan.tools.apple import is_apple_os, XCRun from conan.tools.build import check_min_cppstd -from conan.tools.env import VirtualBuildEnv, Environment +from conan.tools.env import VirtualBuildEnv from conan.tools.files import chdir, copy, get, load, save, replace_in_file from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, VCVars @@ -88,6 +89,22 @@ def generate(self): configure_args.append("-d") save(self, os.path.join(self.source_folder, "configure_args"), " ".join(configure_args)) + @property + def _cxx(self): + compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) + cxx = compilers_by_conf.get("cpp") or VirtualBuildEnv(self).vars().get("CXX") + if cxx: + return cxx + if self.settings.compiler == "apple-clang": + return XCRun(self).cxx + compiler_version = self.settings.compiler.version + major = Version(compiler_version).major + if self.settings.compiler == "gcc": + return shutil.which(f"g++-{compiler_version}") or shutil.which(f"g++-{major}") or shutil.which("g++") or "" + if self.settings.compiler == "clang": + return shutil.which(f"clang++-{compiler_version}") or shutil.which(f"clang++-{major}") or shutil.which("clang++") or "" + return "" + def build(self): with chdir(self, self.source_folder): # Generate dummy header to be able to run `build/gen.py` with `--no-last-commit-position`. @@ -107,16 +124,22 @@ def build(self): # Make sure CXX env var is set, otherwise gn defaults it to clang++ # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 - compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) - os.environ["CXX"] = compilers_by_conf.get("cpp") or VirtualBuildEnv(self).vars().get("CXX") - - self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) - - # Try sleeping one second to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) - time.sleep(1) - - build_args = ["-C", "out", f"-j{os.cpu_count()}"] - self.run("ninja " + " ".join(build_args)) + os.environ["CXX"] = self._cxx + self.output.info(f"Set CXX to '{os.environ['CXX']}'") + + # Try sleeping to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) + err = None + for sleep in [0, 1, 2, 4, 8]: + self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) + time.sleep(sleep) + try: + build_args = ["-C", "out", f"-j{os.cpu_count()}", "-v"] + self.run("ninja " + " ".join(build_args)) + break + except Exception as e: + err = e + if err: + raise err def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) From 435c8812651a038e2040bd7c110583102440d5c4 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 16 Nov 2023 18:03:56 +0200 Subject: [PATCH 08/11] gn: set CXX using Environment --- recipes/gn/all/conanfile.py | 45 +++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 9ad7141c2eb5d..4ae2ae2825625 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -8,7 +8,7 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.apple import is_apple_os, XCRun from conan.tools.build import check_min_cppstd -from conan.tools.env import VirtualBuildEnv +from conan.tools.env import VirtualBuildEnv, Environment from conan.tools.files import chdir, copy, get, load, save, replace_in_file from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, VCVars @@ -73,22 +73,6 @@ def _gn_platform(self): # Assume gn knows about the os return str(self.settings.os).lower() - def generate(self): - env = VirtualBuildEnv(self) - env.generate() - - if is_msvc(self): - vcvars = VCVars(self) - vcvars.generate() - - configure_args = [ - "--no-last-commit-position", - f"--host={self._gn_platform}", - ] - if self.settings.build_type in ["Debug", "RelWithDebInfo"]: - configure_args.append("-d") - save(self, os.path.join(self.source_folder, "configure_args"), " ".join(configure_args)) - @property def _cxx(self): compilers_by_conf = self.conf.get("tools.build:compiler_executables", default={}, check_type=dict) @@ -105,6 +89,28 @@ def _cxx(self): return shutil.which(f"clang++-{compiler_version}") or shutil.which(f"clang++-{major}") or shutil.which("clang++") or "" return "" + def generate(self): + env = VirtualBuildEnv(self) + env.generate() + + # Make sure CXX env var is set, otherwise gn defaults it to clang++ + # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 + env = Environment() + env.define("CXX", self._cxx) + env.vars(self).save_script("conanbuild_gn") + + if is_msvc(self): + vcvars = VCVars(self) + vcvars.generate() + + configure_args = [ + "--no-last-commit-position", + f"--host={self._gn_platform}", + ] + if self.settings.build_type in ["Debug", "RelWithDebInfo"]: + configure_args.append("-d") + save(self, os.path.join(self.source_folder, "configure_args"), " ".join(configure_args)) + def build(self): with chdir(self, self.source_folder): # Generate dummy header to be able to run `build/gen.py` with `--no-last-commit-position`. @@ -122,11 +128,6 @@ def build(self): "def GenerateLastCommitPosition(host, header):", "def GenerateLastCommitPosition(host, header):\n return") - # Make sure CXX env var is set, otherwise gn defaults it to clang++ - # https://gn.googlesource.com/gn/+/refs/heads/main/build/gen.py#386 - os.environ["CXX"] = self._cxx - self.output.info(f"Set CXX to '{os.environ['CXX']}'") - # Try sleeping to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) err = None for sleep in [0, 1, 2, 4, 8]: From b0f033877f1b2dfef62a9ba815b4a2d03d14797b Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Mon, 25 Dec 2023 20:19:57 +0200 Subject: [PATCH 09/11] gn: try to fix apple-clang test_package --- recipes/gn/all/test_package/conanfile.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/recipes/gn/all/test_package/conanfile.py b/recipes/gn/all/test_package/conanfile.py index 734e9293c87bd..4a3175e52589e 100644 --- a/recipes/gn/all/test_package/conanfile.py +++ b/recipes/gn/all/test_package/conanfile.py @@ -3,13 +3,14 @@ from conan import ConanFile from conan.tools.apple import is_apple_os from conan.tools.build import can_run, cross_building +from conan.tools.env import VirtualRunEnv, VirtualBuildEnv from conan.tools.layout import basic_layout from conan.tools.microsoft import unix_path class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" - generators = "VirtualRunEnv", "VCVars" + generators = "VCVars" test_type = "explicit" def build_requirements(self): @@ -34,6 +35,11 @@ def _target_cpu(self): "x86_64": "x64", }.get(str(self.settings.arch), str(self.settings.arch)) + def generate(self): + VirtualBuildEnv(self).generate() + VirtualRunEnv(self).generate(scope="run") + VirtualRunEnv(self).generate(scope="build") + def build(self): if not cross_building(self): rel_bindir = unix_path(self, os.path.relpath(os.path.join(self.cpp.build.bindir), os.getcwd())) From 8f593853446e251f2f1319ed5526754f31d55d8e Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Tue, 19 Mar 2024 15:46:57 +0200 Subject: [PATCH 10/11] gn: drop retry with sleep temporarily --- recipes/gn/all/conanfile.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/recipes/gn/all/conanfile.py b/recipes/gn/all/conanfile.py index 4ae2ae2825625..3e55e76b8eb62 100644 --- a/recipes/gn/all/conanfile.py +++ b/recipes/gn/all/conanfile.py @@ -128,25 +128,13 @@ def build(self): "def GenerateLastCommitPosition(host, header):", "def GenerateLastCommitPosition(host, header):\n return") - # Try sleeping to avoid time skew of the generated ninja.build file (and having to re-run build/gen.py) - err = None - for sleep in [0, 1, 2, 4, 8]: - self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) - time.sleep(sleep) - try: - build_args = ["-C", "out", f"-j{os.cpu_count()}", "-v"] - self.run("ninja " + " ".join(build_args)) - break - except Exception as e: - err = e - if err: - raise err + self.run(f"{sys.executable} build/gen.py " + load(self, "configure_args")) + self.run(f"ninja -C out -j{os.cpu_count()} -v") def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) if self.settings.os == "Windows": - copy(self, - "gn.exe", + copy(self, "gn.exe", src=os.path.join(self.source_folder, "out"), dst=os.path.join(self.package_folder, "bin")) else: From 93347945fbf79e526df784cc6ddb513ffc2f78ad Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 25 Apr 2024 15:22:01 +0300 Subject: [PATCH 11/11] gn: drop test_v1_package --- recipes/gn/all/test_v1_package/conanfile.py | 69 --------------------- 1 file changed, 69 deletions(-) delete mode 100644 recipes/gn/all/test_v1_package/conanfile.py diff --git a/recipes/gn/all/test_v1_package/conanfile.py b/recipes/gn/all/test_v1_package/conanfile.py deleted file mode 100644 index 16b457e153391..0000000000000 --- a/recipes/gn/all/test_v1_package/conanfile.py +++ /dev/null @@ -1,69 +0,0 @@ -from conans import ConanFile, CMake, tools -from contextlib import contextmanager -import os - - -class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - - def build_requirements(self): - self.build_requires("ninja/1.10.2") - - @contextmanager - def _build_context(self): - if self.settings.compiler == "Visual Studio": - with tools.vcvars(self.settings): - yield - else: - compiler_defaults = {} - if self.settings.compiler == "gcc": - compiler_defaults = { - "CC": "gcc", - "CXX": "g++", - "AR": "ar", - "LD": "g++", - } - elif self.settings.compiler in ("apple-clang", "clang"): - compiler_defaults = { - "CC": "clang", - "CXX": "clang++", - "AR": "ar", - "LD": "clang++", - } - env = {} - for k in ("CC", "CXX", "AR", "LD"): - v = tools.get_env(k, compiler_defaults.get(k, None)) - if v: - env[k] = v - with tools.environment_append(env): - yield - - @property - def _target_os(self): - if tools.is_apple_os(self.settings.os): - return "mac" - # Assume gn knows about the os - return { - "Windows": "win", - }.get(str(self.settings.os), str(self.settings.os).lower()) - - @property - def _target_cpu(self): - return { - "x86_64": "x64", - }.get(str(self.settings.arch), str(self.settings.arch)) - - def build(self): - if not tools.cross_building(self.settings): - with tools.chdir(os.path.join(self.source_folder, os.pardir, "test_package")): - gn_args = [ - os.path.relpath(os.path.join(self.build_folder, "bin"), os.getcwd()).replace("\\", "/"), - '--args="target_os=\\"{os_}\\" target_cpu=\\"{cpu}\\""'.format(os_=self._target_os, cpu=self._target_cpu), - ] - self.run(f"gn gen {' '.join(gn_args)}", run_environment=True) - with self._build_context(): - self.run(f"ninja -v -j{tools.cpu_count()} -C bin", run_environment=True) - - def test(self): - if not tools.cross_building(self.settings): - self.run(os.path.join("bin", "test_package"), run_environment=True)