forked from Maratyszcza/confu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 029d7a4
Showing
43 changed files
with
2,206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Ninja files | ||
.ninja_deps | ||
.ninja_log | ||
build.ninja | ||
|
||
# PyCharm project files | ||
.idea/ | ||
|
||
# Build objects and artifacts | ||
confu.egg-info/ | ||
dist/ | ||
docs/ | ||
*.pyc | ||
*.pyo | ||
|
||
# System files | ||
.DS_Store | ||
.DS_Store? | ||
._* | ||
.Spotlight-V100 | ||
.Trashes | ||
ehthumbs.db | ||
Thumbs.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2017 Georgia Institute of Technology | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include confu/recipes/*.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/usr/bin/env python | ||
|
||
from confu.__main__ import main | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
__copyright__ = "Copyright 2017, Georgia Institute of Technology" | ||
__license__ = "MIT" | ||
__version_info__ = ('0', '0', '1') | ||
__version__ = '.'.join(__version_info__) | ||
__maintainer__ = "Marat Dukhan" | ||
__email__ = "[email protected]" | ||
|
||
import logging | ||
logger = logging.getLogger("confu") | ||
logger.setLevel(logging.INFO) | ||
|
||
console_handler = logging.StreamHandler() | ||
console_handler.setLevel(logging.INFO) | ||
|
||
|
||
class ConsoleFormatter(logging.Formatter): | ||
def __init__(self): | ||
super(ConsoleFormatter, self).__init__("%(message)s") | ||
|
||
def format(self, record): | ||
message = super(ConsoleFormatter, self).format(record) | ||
if record.levelname in ["DEBUG", "INFO"]: | ||
return message[0].upper() + message[1:] | ||
else: | ||
return { | ||
"WARNING": "Warning", "ERROR": "Error", "CRITICAL": "Fatal error" | ||
}[record.levelname] + ": " + message[0].lower() + message[1:] | ||
|
||
console_formatter = ConsoleFormatter() | ||
console_handler.setFormatter(console_formatter) | ||
logger.addHandler(console_handler) | ||
|
||
|
||
from confu.builds import Build | ||
from confu.platform import Platform | ||
|
||
|
||
def standard_parser(description="Confu configuration script"): | ||
import argparse | ||
|
||
from os import linesep | ||
from confu.platform import host, possible_targets | ||
|
||
parser = argparse.ArgumentParser(description=description, | ||
formatter_class=argparse.RawTextHelpFormatter) | ||
parser.add_argument("--target", dest="target", metavar="PLATFORM", type=Platform, | ||
default=host.name, | ||
help="platform where the code will run. Potential options:" + linesep + | ||
" " + host.name + " (default)" + linesep + | ||
linesep.join(" " + target for target in possible_targets[1:])) | ||
parser.add_argument("--toolchain", dest="toolchain", metavar="TOOLCHAIN", | ||
choices=["auto", "gnu", "clang"], default="auto", | ||
help="toolchain to use for compilation. Potential options:" + linesep + | ||
linesep.join(" " + name for name in ["auto (default)", "gnu", "clang"])) | ||
|
||
|
||
|
||
return parser |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#!/usr/bin/env python | ||
|
||
import argparse | ||
import logging | ||
|
||
|
||
logger = logging.getLogger("confu") | ||
|
||
|
||
def setup_deps(options, unparsed_args): | ||
import pygit2 | ||
|
||
import confu.recipes | ||
import types | ||
builtin_recipes = [name for name in confu.recipes.__dict__ | ||
if isinstance(confu.recipes.__dict__[name], types.ModuleType)] | ||
|
||
preparsed_args = list() | ||
for arg in unparsed_args: | ||
# TODO: more robust checks | ||
if arg.startswith("--with-") and "=" in arg: | ||
preparsed_args += arg.split("=", 1) | ||
else: | ||
preparsed_args.append(arg) | ||
|
||
dependency_paths = dict() | ||
|
||
import os | ||
for with_arg, path in zip(preparsed_args[0::2], preparsed_args[1::2]): | ||
path = os.path.abspath(os.path.expanduser(os.path.normpath(path))) | ||
dep_name = with_arg[len("--with-"):] | ||
dependency_paths[dep_name] = path | ||
|
||
def setup_project_deps(project_dir, root_dir, namespace=""): | ||
import confu.manifest | ||
project = confu.manifest.Project.from_root(project_dir) | ||
|
||
deps_dir = os.path.join(root_dir, "deps") | ||
if project.deps and not os.path.isdir(deps_dir): | ||
os.mkdir(deps_dir) | ||
|
||
for dep in project.deps: | ||
dep_dir = os.path.join(deps_dir, dep.name) | ||
qualified_name = dep.name if not namespace else namespace + ":" + dep.name | ||
if os.path.exists(dep_dir): | ||
logger.info("reuse dependency {name} from {path}".format( | ||
name=qualified_name, path=dep_dir)) | ||
elif dep.name in dependency_paths: | ||
logger.info("link dependency {name} from {path}".format( | ||
name=qualified_name, path=dependency_paths[dep.name])) | ||
os.symlink(dependency_paths[dep.name], dep_dir) | ||
elif dep.url is not None: | ||
logger.info("fetch dependency {name} from {url}".format( | ||
name=qualified_name, url=dep.url)) | ||
pygit2.clone_repository(dep.url, dep_dir) | ||
elif dep.name in builtin_recipes: | ||
logger.info("setup dependency {name} using built-in recipe confu.recipes.{name}" | ||
.format(name=qualified_name)) | ||
recipe = confu.recipes.__dict__[dep.name] | ||
recipe.setup(dep_dir) | ||
else: | ||
logger.critical("no source provided for dependency {name} ({qname})" | ||
.format(name=dep.name, qname=qualified_name)) | ||
|
||
setup_project_deps(dep_dir, root_dir, | ||
namespace=dep.name if not namespace else namespace + ":" + dep.name) | ||
|
||
import os | ||
root_dir = os.path.abspath(os.getcwd()) | ||
|
||
setup_project_deps(root_dir, root_dir) | ||
|
||
|
||
parser = argparse.ArgumentParser( | ||
description="Confu: cross-platform C/C++ configuration system") | ||
subparsers = parser.add_subparsers(title="commands", | ||
description="supported commands") | ||
setup_parser = subparsers.add_parser("setup", help="set up dependencies") | ||
setup_parser.add_argument("args", nargs=argparse.REMAINDER) | ||
setup_parser.set_defaults(process=setup_deps) | ||
|
||
|
||
def main(): | ||
options, unparsed_args = parser.parse_known_args() | ||
options.process(options, unparsed_args) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from confu.builds.base import Build | ||
from confu.builds.unix import UnixBuild | ||
from confu.builds.pnacl import PNaClBuild | ||
from confu.builds.emscripten import EmscriptenBuild | ||
from confu.builds.module import Module, ModuleCollection | ||
from confu.builds.deps import DependencyCollection |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import os | ||
import logging | ||
|
||
import six | ||
|
||
logger = logging.getLogger("confu") | ||
|
||
from confu.builds.state import State | ||
|
||
|
||
class Build(State): | ||
def __init__(self, root_dir, target): | ||
super(Build, self).__init__(root_dir) | ||
if self.__class__ is Build: | ||
raise TypeError("This constructor is intended for use by subclasses only. " | ||
"Use static method Build.from_options to create an abstract Build class") | ||
import confu.platform | ||
assert isinstance(target, confu.platform.Platform) | ||
|
||
self.target = target | ||
|
||
from confu.manifest import Project | ||
self.manifest = Project.from_root(root_dir) | ||
logger.debug("parsed manifest for " + str(self.manifest)) | ||
|
||
from confu.builds import DependencyCollection | ||
self.deps = DependencyCollection(root_dir, self.manifest, self.target) | ||
|
||
from confu.builds import ModuleCollection | ||
self.modules = ModuleCollection() | ||
|
||
from confu.tools import ToolCollection | ||
self.tools = ToolCollection(self.target) | ||
|
||
@staticmethod | ||
def from_options(options, root_dir=None, **kwargs): | ||
from confu.utils import get_root_dir | ||
if root_dir is None: | ||
root_dir = get_root_dir() | ||
|
||
import confu.globals | ||
if confu.globals.root_dir is None: | ||
confu.globals.root_dir = root_dir | ||
logger.info("detected root directory: " + root_dir) | ||
|
||
from confu.platform import host | ||
if options.target.is_emscripten: | ||
from confu.builds import EmscriptenBuild | ||
return EmscriptenBuild(root_dir, options.target, options.toolchain) | ||
elif options.target == host or options.target.is_nacl: | ||
from confu.builds import UnixBuild, PNaClBuild | ||
if options.target.is_pnacl: | ||
return PNaClBuild(root_dir, options.target, options.toolchain) | ||
else: | ||
return UnixBuild(root_dir, options.target, options.toolchain) | ||
else: | ||
raise ValueError("Unsupported target platform {target}".format(target=options.target.name)) | ||
|
||
@property | ||
def active_module(self): | ||
return self.modules._active | ||
|
||
def cc(self, source_path): | ||
raise EnvironmentError("Compilation of C codes is not supported for {target}" | ||
.format(target=options.target.name)) | ||
|
||
def cxx(self, source_path): | ||
raise EnvironmentError("Compilation of C++ codes is not supported for {target}" | ||
.format(target=options.target.name)) | ||
|
||
def peachpy(self, source_path): | ||
raise EnvironmentError("Compilation of PeachPy codes is not supported for {target}" | ||
.format(target=options.target.name)) | ||
|
||
def export_cpath(self, include_dir, include_paths, add_to_include_dirs=True): | ||
from confu.validators import validate_include_dir | ||
include_dir = validate_include_dir(include_dir, self.root_dir) | ||
self.active_module.cpath.append(include_dir) | ||
if add_to_include_dirs: | ||
self._include_dirs.append(include_dir) | ||
|
||
def static_library(self, name, object_files): | ||
raise EnvironmentError("Static libraries are not supported for {target}" | ||
.format(target=options.target.name)) | ||
|
||
def dynamic_library(self, name, object_files): | ||
raise EnvironmentError("Dynamically loaded or shared libraries are not supported on {target}" | ||
.format(target=options.target.name)) | ||
|
||
def library(self, name, object_files): | ||
raise EnvironmentError("Function libraries are not supported for {target}" | ||
.format(target=options.target.name)) | ||
|
||
def plugin(self, name, object_files): | ||
raise EnvironmentError("Plugin modules are not supported on {target}" | ||
.format(target=options.target.name)) | ||
|
||
def executable(self, name, object_files): | ||
import confu.platform | ||
raise EnvironmentError("Executables are not supported on {target}" | ||
.format(target=options.target.name)) | ||
|
||
def unittest(self, name, object_files): | ||
import confu.platform | ||
if confu.platform.host == options.target: | ||
raise EnvironmentError("Unit tests are not supported on {target}" | ||
.format(target=options.target.name)) | ||
else: | ||
raise EnvironmentError("Unit tests are not supported in cross-compilation from {host} to {target}" | ||
.format(host=confu.platform.host, target=options.target.name)) | ||
|
||
def smoketest(self, name, object_files): | ||
import confu.platform | ||
if confu.platform.host == options.target: | ||
raise EnvironmentError("Smoke tests are not supported on {target}" | ||
.format(target=options.target.name)) | ||
else: | ||
raise EnvironmentError("Smoke tests are not supported in cross-compilation from {host} to {target}" | ||
.format(host=confu.platform.host, target=options.target.name)) | ||
|
||
def benchmark(self, name, object_files): | ||
import confu.platform | ||
if confu.platform.host == options.target: | ||
raise EnvironmentError("Benchmarks are not supported on {target}" | ||
.format(target=options.target.name)) | ||
else: | ||
raise EnvironmentError("Benchmarks are not supported in cross-compilation from {host} to {target}" | ||
.format(host=confu.platform.host, target=options.target.name)) | ||
|
||
def generate(self): | ||
import ninja_syntax | ||
import confu.globals | ||
confu.globals.build_ninja_path = os.path.join(self.root_dir, "build.ninja") | ||
with open(confu.globals.build_ninja_path, "w") as build_ninja: | ||
ninja = ninja_syntax.Writer(build_ninja) | ||
self.generate_variables(ninja) | ||
self.generate_rules(ninja) | ||
|
||
import sys | ||
configure_path = os.path.abspath(os.path.normpath(sys.argv[0])) | ||
args = sys.argv[1:] | ||
ninja.rule("configure", configure_path + " $args", | ||
description="CONFIGURE $args", pool="console", generator=True) | ||
ninja.rule("clean", "ninja -f $config -t clean", | ||
description="CLEAN", pool="console") | ||
|
||
ninja.build("build.ninja", "configure", configure_path, | ||
variables={"args": " ".join(args)}) | ||
ninja.build("clean", "clean", | ||
variables={"config": confu.globals.build_ninja_path}) | ||
|
||
self.modules._record(ninja) | ||
|
||
def generate_variables(self, ninja): | ||
raise NotImplementedError() | ||
|
||
def generate_rules(self, ninja): | ||
raise NotImplementedError() |
Oops, something went wrong.