-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gn: add initial gn recipe #5433
Changes from 8 commits
831003f
07411a6
b341e5e
e5e5f59
14bbf05
e8b5e78
b502038
9a38b25
9af7ada
bf76d8d
abe0ec1
f0988c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
sources: | ||
"cci.20210429": | ||
url: "https://gn.googlesource.com/gn/+archive/6771ce569fb4803dad7a427aa2e2c23e960b917e.tar.gz" | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
from conans import ConanFile, tools | ||
from conans.errors import ConanInvalidConfiguration | ||
from contextlib import contextmanager | ||
import os | ||
import textwrap | ||
import time | ||
|
||
required_conan_version = ">=1.33.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 = ("LGPL-3.0", "GPL-2.0") | ||
madebr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
homepage = "https://gn.googlesource.com/" | ||
settings = "os", "arch", "compiler", "build_type" | ||
|
||
@property | ||
def _source_subfolder(self): | ||
return "source_subfolder" | ||
|
||
@property | ||
def _minimum_compiler_version_supporting_cxx17(self): | ||
return { | ||
"Visual Studio": 15, | ||
"gcc": 7, | ||
"clang": 4, | ||
"apple-clang": 10, | ||
}.get(str(self.settings.compiler)) | ||
|
||
def configure(self): | ||
if self.settings.compiler.cppstd: | ||
tools.check_min_cppstd(self, 17) | ||
else: | ||
if self._minimum_compiler_version_supporting_cxx17: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've seen this pattern over and over, I'm wondering if this should be a conan built in tool. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some util functions would be nice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. One day... 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The C++ standard is not enough since the STL support changes between some minor versions it's a manual process for many projects |
||
if tools.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.get(**self.conan_data["sources"][self.version], destination=self._source_subfolder) | ||
|
||
def build_requirements(self): | ||
self.build_requires("ninja/1.10.2") | ||
madebr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@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_): | ||
return "darwin" | ||
if compiler == "Visual Studio": | ||
return "msvc" | ||
# Assume gn knows about the os | ||
return str(os_).lower() | ||
|
||
def build(self): | ||
with tools.chdir(self._source_subfolder): | ||
with self._build_context(): | ||
tools.save(os.path.join("src", "gn", "last_commit_position.h"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a comment about what this is for?
madebr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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("python build/gen.py {}".format(" ".join(conf_args)), run_environment=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it require cpython in build requirement when packaged? Maybe add a TODO? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'll add a todo. |
||
# 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) | ||
|
||
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") | ||
|
||
def package_info(self): | ||
bin_path = os.path.join(self.package_folder, "bin") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these lines really necessary? It is my understanding that conan exposes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not needed when doing crossbuilds ( |
||
self.output.info("Appending PATH environment variable: {}".format(bin_path)) | ||
self.env_info.PATH.append(bin_path) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# The location of the build configuration file. | ||
buildconfig = "//config/BUILDCONFIG.gn" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
executable("test_package") { | ||
sources = ["test_package.cpp"] | ||
|
||
deps = [ | ||
":test_shared", | ||
":test_static", | ||
] | ||
} | ||
|
||
shared_library("test_shared") { | ||
defines = ["TEST_SHARED_BUILD"] | ||
sources = [ | ||
"test_shared.cpp", | ||
] | ||
} | ||
|
||
static_library("test_static") { | ||
sources = [ | ||
"test_static.cpp", | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this not be re-used some how, I hate duplication like this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These environment variables are closely coupled with the |
||
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) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright 2014 The Chromium Authors. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license that can be | ||
# found in the LICENSE file. | ||
config("compiler_defaults") { | ||
if (current_os == "linux") { | ||
cflags = [ | ||
"-fPIC", | ||
"-pthread", | ||
] | ||
} | ||
if (current_os == "windows") { | ||
cflags_cc = [ | ||
"-EHsc", | ||
] | ||
} | ||
} | ||
config("executable_ldconfig") { | ||
if (!is_mac && current_os != "windows") { | ||
ldflags = [ | ||
"-Wl,-rpath=\$ORIGIN/", | ||
"-Wl,-rpath-link=", | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Copyright 2014 The Chromium Authors. All rights reserved. | ||
# Use of this source code is governed by a BSD-style license that can be | ||
# found in the LICENSE file. | ||
|
||
if (target_os == "") { | ||
target_os = host_os | ||
} | ||
if (target_cpu == "") { | ||
target_cpu = host_cpu | ||
} | ||
if (current_cpu == "") { | ||
current_cpu = target_cpu | ||
} | ||
if (current_os == "") { | ||
current_os = target_os | ||
} | ||
is_windows = host_os == "win" && current_os == "win" && target_os == "win" | ||
is_linux = host_os == "linux" && current_os == "linux" && target_os == "linux" | ||
is_mac = host_os == "mac" && current_os == "mac" && target_os == "mac" | ||
# All binary targets will get this list of configs by default. | ||
_shared_binary_target_configs = [ "//config:compiler_defaults" ] | ||
# Apply that default list to the binary target types. | ||
set_defaults("executable") { | ||
configs = _shared_binary_target_configs | ||
# Executables get this additional configuration. | ||
configs += [ "//config:executable_ldconfig" ] | ||
} | ||
set_defaults("static_library") { | ||
configs = _shared_binary_target_configs | ||
} | ||
set_defaults("shared_library") { | ||
configs = _shared_binary_target_configs | ||
} | ||
set_defaults("source_set") { | ||
configs = _shared_binary_target_configs | ||
} | ||
if (is_windows) { | ||
set_default_toolchain("//config/toolchain:msvc") | ||
} else { | ||
set_default_toolchain("//config/toolchain:gcc") | ||
} | ||
|
||
print("current_os:", current_os) | ||
print("current_cpu:", current_cpu) | ||
print("host_os:", host_os) | ||
print("host_cpu:", host_cpu) | ||
print("target_os:", target_os) | ||
print("target_cpu:", target_os) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why no sha256?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It changes all the time.
Some time stamp is probably spoiling the fun.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, their servers produce tarballs on fly, and sha256 is always different, it's pain to package. if someone can help how to get stable tarball URL for gn, help is welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we could mirror this repo on github and have it sync itself automatically using actions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like this actions/checkout#24
But it looks like it only works to sync repos on the same domain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's completely possible.
But somebody/organization should invest some time setting it up...