From 7e4a9220d7781c4c641c47f89ffd177b55b7f9bb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 11 Jan 2013 01:23:08 -0800 Subject: [PATCH] Initial project skeleton. This includes a working gyp-based build of an executable that uses LLVM. --- .gitignore | 68 +++++ .gitmodules | 9 + CONTRIBUTORS.md | 6 + README.md | 94 ++++++- bin/xenia-info | 16 ++ bin/xenia-run | 16 ++ common.gypi | 89 +++++++ include/xenia/xenia.h | 15 ++ src/core/something.cc | 55 ++++ src/core/sources.gypi | 6 + third_party/gyp | 1 + third_party/llvm | 1 + third_party/ninja | 1 + tools/tools.gypi | 7 + tools/xenia-info/xenia-info.cc | 14 ++ tools/xenia-info/xenia-info.gypi | 21 ++ tools/xenia-run/xenia-run.cc | 14 ++ tools/xenia-run/xenia-run.gypi | 21 ++ xenia-build.py | 413 +++++++++++++++++++++++++++++++ xenia.gyp | 55 ++++ xeniarc | 7 + 21 files changed, 920 insertions(+), 9 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CONTRIBUTORS.md create mode 100755 bin/xenia-info create mode 100755 bin/xenia-run create mode 100644 common.gypi create mode 100644 include/xenia/xenia.h create mode 100644 src/core/something.cc create mode 100644 src/core/sources.gypi create mode 160000 third_party/gyp create mode 160000 third_party/llvm create mode 160000 third_party/ninja create mode 100644 tools/tools.gypi create mode 100644 tools/xenia-info/xenia-info.cc create mode 100644 tools/xenia-info/xenia-info.gypi create mode 100644 tools/xenia-run/xenia-run.cc create mode 100644 tools/xenia-run/xenia-run.gypi create mode 100755 xenia-build.py create mode 100644 xenia.gyp create mode 100644 xeniarc diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ea95dc1c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,68 @@ +# ============================================================================== +# Misc system junk +# ============================================================================== + +.DS_Store +._* +.Spotlight-V100 +.Trashes +.com.apple.* +Thumbs.db +Desktop.ini + +# ============================================================================== +# Projects/IDE files +# ============================================================================== + +# Sublime Text +*.sublime-project +*.sublime-workspace + +# VIM +.*.sw[a-z] +*.un~ +Session.vim + +# TextMate +*.tmproj +*.tmproject +tmtags + +# Eclipse +.project +.metadata + +# ============================================================================== +# Temp generated code +# ============================================================================== + +*.py[co] +.coverage + +# ============================================================================== +# Logs and dumps +# ============================================================================== + +npm-debug.log +private/ + +# ============================================================================== +# Build system output +# ============================================================================== + +# npm/node +.lock-wscript +node_modules/ +node_modules/**/build/ +node_modules/.bin/ + +# coverage/etc +scratch/ + +.anvil-cache +.build-cache/ +build/ +build-out/ +build-gen/ +build-bin/ +build-test/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..3863f7082 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "third_party/ninja"] + path = third_party/ninja + url = git://github.com/martine/ninja.git +[submodule "third_party/llvm"] + path = third_party/llvm + url = http://llvm.org/git/llvm.git +[submodule "third_party/gyp"] + path = third_party/gyp + url = https://github.com/benvanik/gyp.git diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..857194e51 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +Contributors +------------ + +Names should be added to this file like so: `Name or Organization ` + +* Ben Vanik diff --git a/README.md b/README.md index c808bcd18..76ecc1271 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,12 @@ Coming soon (maybe): ## Quickstart git clone https://github.com/benvanik/xenia.git - ./xenia-build.sh setup - ./xenia-build.sh build - ./bin/xenia some.xex + cd xenia && source xeniarc + xb setup + xb build + ./bin/xenia-run some.xex -## Building - -### Requirements +## Requirements You must have a 64-bit machine for building and running the project. Always run your system updater before building and make sure you have the latest @@ -43,8 +42,85 @@ Windows SDK, the full DirectX SDK, and the Kinect SDK. #### OS X -* [Xcode 4](http://developer.apple.com/xcode/) +Only tested on OS X 10.8 (Mountain Lion). -### Dependencies +* [Xcode 4](http://developer.apple.com/xcode/) + command line tools +* [Homebrew](http://mxcl.github.com/homebrew/) -TODO +## Building + +A simple build script is included to manage basic tasks such as building +dependencies. + + ./xenia-build.py --help + +The `xeniarc` bash file has some aliases that save some keypresses. + + source xeniarc + xb -> python xenia-build.py + xbb -> python xenia-build.py build + xbc -> python xenia-build.py clean + +### Commands + +#### setup + +Run this on initial checkout to pull down all dependencies and setup LLVM. + + xb setup + +#### pull + +Does a `git pull` in addition to updating submodules and rebuilding dependencies +and gyp outputs. Use this, if possible, instead of git pull. + + xb pull + +#### gyp + +Updates all of the supported gyp projects. If you're using Visual Studio or +Xcode to build or debug your projects you'll need to run this after you change +gyp/gypi files. + + xb gyp + +#### build + +Builds all xenia targets using ninja. Release is built by default; specify +`--debug` to build the debug configuration. + + xb build + xb build --debug + +#### clean + +Cleans just xenia outputs from the build/ directory. A following build will just +have the rebuild xenia and not all of the dependencies. + + xb clean + +#### nuke + +Cleans up xenia outputs as well as all dependencies. A full build will be +required after this - including LLVM - so only do this if you want to reclaim +your disk space or something is really wrong. + + xb nuke + +## Running + +Use the wrapper shell scripts under `bin/` to run tools. They will ensure the +tools are built (but not that they are up to date) before running and allow +switching between the debug and release variants with `--debug`. + +### xenia-info + +Dumps information about a xex file. + + ./bin/xenia-info some.xex + +### xenia-run + +Runs a xex. + + ./bin/xenia-run some.xex diff --git a/bin/xenia-info b/bin/xenia-info new file mode 100755 index 000000000..4d7135fa8 --- /dev/null +++ b/bin/xenia-info @@ -0,0 +1,16 @@ +#!/bin/sh + +DIR="$( cd "$( dirname "$0" )" && pwd )" + +CONFIG=release +case "$*" in +(*--debug*) CONFIG=debug;; +esac + +EXEC=$DIR/../build/xenia/$CONFIG/xenia-info + +if [ ! -f "$EXEC" ]; then + python $DIR/../xenia-build.py build --$CONFIG +fi + +$EXEC "$@" diff --git a/bin/xenia-run b/bin/xenia-run new file mode 100755 index 000000000..33aace055 --- /dev/null +++ b/bin/xenia-run @@ -0,0 +1,16 @@ +#!/bin/sh + +DIR="$( cd "$( dirname "$0" )" && pwd )" + +CONFIG=release +case "$*" in +(*--debug*) CONFIG=debug;; +esac + +EXEC=$DIR/../build/xenia/$CONFIG/xenia-run + +if [ ! -f "$EXEC" ]; then + python $DIR/../xenia-build.py build --$CONFIG +fi + +$EXEC "$@" diff --git a/common.gypi b/common.gypi new file mode 100644 index 000000000..c6517c644 --- /dev/null +++ b/common.gypi @@ -0,0 +1,89 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'default_configuration': 'release', + + 'variables': { + 'configurations': { + 'debug': { + }, + 'release': { + }, + }, + + # LLVM paths. + 'llvm_path': 'build/llvm/release/', + 'llvm_config': '<(llvm_path)bin/llvm-config', + }, + + + 'target_defaults': { + 'include_dirs': [ + 'include/', + ], + + 'configurations': { + 'debug': { + 'defines': [ + 'DEBUG', + ], + 'msvs_configuration_attributes': { + 'OutputDirectory': '<(DEPTH)\\build\\xenia\\debug', + }, + 'msvs_settings': { + 'VCCLCompilerTool': { + 'Optimization': '2', + 'BasicRuntimeChecks': '0', # disable /RTC1 when compiling /O2 + 'DebugInformationFormat': '3', + 'ExceptionHandling': '0', + 'RuntimeTypeInfo': 'false', + 'OmitFramePointers': 'false', + }, + 'VCLinkerTool': { + 'LinkIncremental': '2', + 'GenerateDebugInformation': 'true', + 'StackReserveSize': '2097152', + }, + }, + }, + 'release': { + 'defines': [ + 'RELEASE', + ], + 'msvs_configuration_attributes': { + 'OutputDirectory': '<(DEPTH)\\build\\xenia\\release', + }, + 'msvs_settings': { + 'VCCLCompilerTool': { + 'Optimization': '2', + 'InlineFunctionExpansion': '2', + 'EnableIntrinsicFunctions': 'true', + 'FavorSizeOrSpeed': '0', + 'ExceptionHandling': '0', + 'RuntimeTypeInfo': 'false', + 'OmitFramePointers': 'false', + 'StringPooling': 'true', + }, + 'VCLinkerTool': { + 'LinkIncremental': '1', + 'GenerateDebugInformation': 'true', + 'OptimizeReferences': '2', + 'EnableCOMDATFolding': '2', + 'StackReserveSize': '2097152', + }, + }, + }, + }, + + 'msvs_configuration_platform': 'x64', + 'msvs_cygwin_shell': '0', + 'scons_settings': { + 'sconsbuild_dir': '<(DEPTH)/build/xenia/', + }, + 'xcode_settings': { + 'SYMROOT': '<(DEPTH)/build/xenia/', + 'ARCHS': [ 'x86_64' ], + 'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', + 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', + }, + }, +} diff --git a/include/xenia/xenia.h b/include/xenia/xenia.h new file mode 100644 index 000000000..497f4b6b6 --- /dev/null +++ b/include/xenia/xenia.h @@ -0,0 +1,15 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_H_ +#define XENIA_H_ + +int some_function(int x); + +#endif // XENIA_H_ diff --git a/src/core/something.cc b/src/core/something.cc new file mode 100644 index 000000000..cdc07f3a8 --- /dev/null +++ b/src/core/something.cc @@ -0,0 +1,55 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include + +using namespace llvm; + +int some_function(int xx) { + LLVMContext &context = getGlobalContext(); + //IRBuilder<> builder(context); + Module *module = new Module("my cool jit", context); + + Constant* c = module->getOrInsertFunction("mul_add", + /*ret type*/ IntegerType::get(context, 32), + /*args*/ IntegerType::get(context, 32), + IntegerType::get(context, 32), + IntegerType::get(context, 32), + /*varargs terminated with null*/ NULL); + + Function* mul_add = cast(c); + mul_add->setCallingConv(CallingConv::C); + + Function::arg_iterator args = mul_add->arg_begin(); + Value* x = args++; + x->setName("x"); + Value* y = args++; + y->setName("y"); + Value* z = args++; + z->setName("z"); + + BasicBlock* block = BasicBlock::Create(getGlobalContext(), "entry", mul_add); + IRBuilder<> builder(block); + + Value* tmp = builder.CreateBinOp(Instruction::Mul, + x, y, "tmp"); + Value* tmp2 = builder.CreateBinOp(Instruction::Add, + tmp, z, "tmp2"); + + builder.CreateRet(tmp2); + + module->dump(); + delete module; + return xx + 4; +} diff --git a/src/core/sources.gypi b/src/core/sources.gypi new file mode 100644 index 000000000..f9abda25b --- /dev/null +++ b/src/core/sources.gypi @@ -0,0 +1,6 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'something.cc', + ], +} diff --git a/third_party/gyp b/third_party/gyp new file mode 160000 index 000000000..12d97efcb --- /dev/null +++ b/third_party/gyp @@ -0,0 +1 @@ +Subproject commit 12d97efcb0d2cbe321ab6f050c2b2311e7048429 diff --git a/third_party/llvm b/third_party/llvm new file mode 160000 index 000000000..b956ec176 --- /dev/null +++ b/third_party/llvm @@ -0,0 +1 @@ +Subproject commit b956ec176a23dff2324c4938c3433c5e5ce2eae5 diff --git a/third_party/ninja b/third_party/ninja new file mode 160000 index 000000000..8a4c9e05f --- /dev/null +++ b/third_party/ninja @@ -0,0 +1 @@ +Subproject commit 8a4c9e05f794162af46939e078ee6464367cafc9 diff --git a/tools/tools.gypi b/tools/tools.gypi new file mode 100644 index 000000000..b38c747db --- /dev/null +++ b/tools/tools.gypi @@ -0,0 +1,7 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'includes': [ + 'xenia-info/xenia-info.gypi', + 'xenia-run/xenia-run.gypi', + ], +} diff --git a/tools/xenia-info/xenia-info.cc b/tools/xenia-info/xenia-info.cc new file mode 100644 index 000000000..80542f47d --- /dev/null +++ b/tools/xenia-info/xenia-info.cc @@ -0,0 +1,14 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +int main() { + return some_function(4); +} diff --git a/tools/xenia-info/xenia-info.gypi b/tools/xenia-info/xenia-info.gypi new file mode 100644 index 000000000..9dda4614e --- /dev/null +++ b/tools/xenia-info/xenia-info.gypi @@ -0,0 +1,21 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'targets': [ + { + 'target_name': 'xenia-info', + 'type': 'executable', + + 'dependencies': [ + 'xeniacore', + ], + + 'include_dirs': [ + '.', + ], + + 'sources': [ + 'xenia-info.cc', + ], + }, + ], +} diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc new file mode 100644 index 000000000..80542f47d --- /dev/null +++ b/tools/xenia-run/xenia-run.cc @@ -0,0 +1,14 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +int main() { + return some_function(4); +} diff --git a/tools/xenia-run/xenia-run.gypi b/tools/xenia-run/xenia-run.gypi new file mode 100644 index 000000000..3dd5a618f --- /dev/null +++ b/tools/xenia-run/xenia-run.gypi @@ -0,0 +1,21 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'targets': [ + { + 'target_name': 'xenia-run', + 'type': 'executable', + + 'dependencies': [ + 'xeniacore', + ], + + 'include_dirs': [ + '.', + ], + + 'sources': [ + 'xenia-run.cc', + ], + }, + ], +} diff --git a/xenia-build.py b/xenia-build.py new file mode 100755 index 000000000..93b33ce9d --- /dev/null +++ b/xenia-build.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python + +# Copyright 2013 Ben Vanik. All Rights Reserved. + +""" +""" + +__author__ = 'ben.vanik@gmail.com (Ben Vanik)' + + +import os +import shutil +import subprocess +import sys + + +def main(): + # Add self to the root search path. + sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) + + # Check python version. + if sys.version_info < (2, 7): + print 'ERROR: python 2.7+ required' + sys.exit(1) + return + + # Grab all commands. + commands = discover_commands() + + # Parse command name and dispatch. + try: + if len(sys.argv) < 2: + raise ValueError('No command given') + command_name = sys.argv[1] + if not commands.has_key(command_name): + raise ValueError('Command "%s" not found' % (command_name)) + + command = commands[command_name] + return_code = run_command(command=command, + args=sys.argv[2:], + cwd=os.getcwd()) + except ValueError: + print usage(commands) + return_code = 1 + except Exception as e: + #print e + raise + return_code = 1 + sys.exit(return_code) + + +def discover_commands(): + """Looks for all commands and returns a dictionary of them. + In the future commands could be discovered on disk. + + Returns: + A dictionary containing name-to-Command mappings. + """ + commands = { + 'setup': SetupCommand(), + 'pull': PullCommand(), + 'gyp': GypCommand(), + 'build': BuildCommand(), + 'clean': CleanCommand(), + 'nuke': NukeCommand(), + } + return commands + + +def usage(commands): + """Gets usage info that can be displayed to the user. + + Args: + commands: A command dictionary from discover_commands. + + Returns: + A string containing usage info and a command listing. + """ + s = 'xenia-build.py command [--help]\n' + s += '\n' + s += 'Commands:\n' + command_names = commands.keys() + command_names.sort() + for command_name in command_names: + s += ' %s\n' % (command_name) + command_help = commands[command_name].help_short + if command_help: + s += ' %s\n' % (command_help) + return s + + +def run_command(command, args, cwd): + """Runs a command with the given context. + + Args: + command: Command to run. + args: Arguments, with the app and command name stripped. + cwd: Current working directory. + + Returns: + 0 if the command succeeded and non-zero otherwise. + + Raises: + ValueError: The command could not be found or was not specified. + """ + # TODO(benvanik): parse arguments/etc. + return command.execute(args, cwd) + + +def has_bin(bin): + """Checks whether the given binary is present. + """ + DEVNULL = open(os.devnull, 'wb') + return True if subprocess.call( + 'which %s' % (bin), shell=True, stdout=DEVNULL) == 0 else False + + +def shell_call(command): + """Executes a shell command. + """ + subprocess.check_call(command, shell=True) + + +class Command(object): + """Base type for commands. + """ + + def __init__(self, name, help_short=None, help_long=None, *args, **kwargs): + """Initializes a command. + + Args: + name: The name of the command exposed to the management script. + help_short: Help text printed alongside the command when queried. + help_long: Extended help text when viewing command help. + """ + self.name = name + self.help_short = help_short + self.help_long = help_long + + def execute(self, args, cwd): + """Executes the command. + + Args: + args: Arguments list. + cwd: Current working directory. + + Returns: + Return code of the command. + """ + return 1 + + +def post_update_deps(config): + """Runs common tasks that should be executed after any deps are changed. + + Args: + config: 'debug' or 'release'. + """ + print '- building llvm...' + shell_call('third_party/ninja/ninja -C build/llvm/%s-obj/ install' % (config)) + print '' + + +class SetupCommand(Command): + """'setup' command.""" + + def __init__(self, *args, **kwargs): + super(SetupCommand, self).__init__( + name='setup', + help_short='Setup the build environment.', + *args, **kwargs) + + def execute(self, args, cwd): + print 'Setting up the build environment...' + print '' + + # Setup submodules. + print '- git submodule init / update...' + shell_call('git submodule init') + shell_call('git submodule update') + print '' + + # LLVM needs to pull with --rebase. + # TODO(benvanik): any way to do this to just the submodule? + #shell_call('git config branch.master.rebase true') + + # Disable core.filemode on Windows to prevent weird file mode diffs in git. + # TODO(benvanik): check cygwin test - may be wrong when using Windows python + if os.path.exists('/Cygwin.bat'): + print '- setting filemode off on cygwin...' + shell_call('git config core.filemode false') + shell_call('git submodule foreach git config core.filemode false') + print '' + + # Run the ninja bootstrap to build it, if it's missing. + if not os.path.exists('third_party/ninja/ninja'): + print '- preparing ninja...' + shell_call('python third_party/ninja/bootstrap.py') + print '' + + # Ensure cmake is present. + if not has_bin('cmake'): + print '- installing cmake...' + if has_bin('brew'): + shell_call('brew install cmake') + elif has_bin('apt-get'): + shell_call('sudo apt-get install cmake') + else: + print 'ERROR: need to install cmake, use:' + print 'http://www.cmake.org/cmake/resources/software.html' + return 1 + print '' + + # LLVM. + print '- preparing llvm...' + #generator = 'Visual Studio 10 Win64' + generator = 'Ninja' + def prepareLLVM(path, obj_path, mode): + os.chdir(cwd) + if not os.path.exists(path): + os.makedirs(path) + if not os.path.exists(obj_path): + os.makedirs(obj_path) + os.chdir(obj_path) + shell_call(' '.join([ + 'PATH=$PATH:../../../third_party/ninja/', + 'cmake', + '-G"%s"' % (generator), + '-DCMAKE_INSTALL_PREFIX:STRING=../../../%s' % (path), + '-DCMAKE_BUILD_TYPE:STRING=%s' % (mode), + '-DLLVM_TARGETS_TO_BUILD:STRING="X86"', + '-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF', + '-DLLVM_INCLUDE_TESTS:BOOL=OFF', + '../../../third_party/llvm/', + ])) + os.chdir(cwd) + prepareLLVM('build/llvm/debug/', 'build/llvm/debug-obj/', 'Debug') + prepareLLVM('build/llvm/release/', 'build/llvm/release-obj/', 'Release') + print '' + + post_update_deps('debug') + post_update_deps('release') + + print '- running gyp...' + run_all_gyps() + print '' + + print 'Success!' + return 0 + + +class PullCommand(Command): + """'pull' command.""" + + def __init__(self, *args, **kwargs): + super(PullCommand, self).__init__( + name='pull', + help_short='Pulls the repo and all dependencies.', + *args, **kwargs) + + def execute(self, args, cwd): + print 'Pulling...' + print '' + + print '- pulling self...' + shell_call('git pull') + print '' + + print '- pulling dependencies...' + shell_call('git submodule update') + print '' + + post_update_deps('debug') + post_update_deps('release') + + print '- running gyp...' + run_all_gyps() + print '' + + print 'Success!' + return 0 + + +def run_gyp(format): + """Runs gyp on the main project with the given format. + + Args: + format: gyp -f value. + """ + shell_call(' '.join([ + 'third_party/gyp/gyp', + '-f %s' % (format), + # Set the VS version. + # TODO(benvanik): allow user to set? + '-G msvs_version=2010', + # Removes the out/ from ninja builds. + '-G output_dir=.', + '--depth=.', + '--generator-output=build/xenia/', + 'xenia.gyp', + ])) + + +def run_all_gyps(): + """Runs all gyp configurations. + """ + run_gyp('ninja') + run_gyp('xcode') + run_gyp('msvs') + + +class GypCommand(Command): + """'gyp' command.""" + + def __init__(self, *args, **kwargs): + super(GypCommand, self).__init__( + name='gyp', + help_short='Runs gyp to update all projects.', + *args, **kwargs) + + def execute(self, args, cwd): + print 'Running gyp...' + print '' + + # Update GYP. + run_all_gyps() + + print 'Success!' + return 0 + + +class BuildCommand(Command): + """'build' command.""" + + def __init__(self, *args, **kwargs): + super(BuildCommand, self).__init__( + name='build', + help_short='Builds the project.', + *args, **kwargs) + + def execute(self, args, cwd): + # TODO(benvanik): add arguments: + # --force + debug = '--debug' in args + config = 'debug' if debug else 'release' + + # If there's no LLVM we may have been cleaned - run setup again. + if not os.path.exists('build/llvm/'): + print 'Missing LLVM, running setup...' + shell_call('python xenia-build.py setup') + print '' + + print 'Building %s...' % (config) + print '' + + print '- running gyp for ninja...' + run_gyp('ninja') + print '' + + print '- building xenia in %s...' % (config) + shell_call('third_party/ninja/ninja -C build/xenia/%s' % (config)) + print '' + + print 'Success!' + return 0 + + +class CleanCommand(Command): + """'clean' command.""" + + def __init__(self, *args, **kwargs): + super(CleanCommand, self).__init__( + name='clean', + help_short='Removes intermediate files and build output.', + *args, **kwargs) + + def execute(self, args, cwd): + print 'Cleaning build artifacts...' + print '' + + print '- removing build/xenia/...' + if os.path.isdir('build/xenia/'): + shutil.rmtree('build/xenia/') + print '' + + print 'Success!' + return 0 + + +class NukeCommand(Command): + """'nuke' command.""" + + def __init__(self, *args, **kwargs): + super(NukeCommand, self).__init__( + name='nuke', + help_short='Removes all build/ output.', + *args, **kwargs) + + def execute(self, args, cwd): + print 'Cleaning build artifacts...' + print '' + + print '- removing build/...' + if os.path.isdir('build/'): + shutil.rmtree('build/') + print '' + + print 'Success!' + return 0 + + +if __name__ == '__main__': + main() diff --git a/xenia.gyp b/xenia.gyp new file mode 100644 index 000000000..309e683a7 --- /dev/null +++ b/xenia.gyp @@ -0,0 +1,55 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'includes': [ + 'common.gypi', + 'tools/tools.gypi', + ], + + 'targets': [ + { + 'target_name': 'xeniacore', + 'product_name': 'xeniacore', + 'type': 'static_library', + + 'direct_dependent_settings': { + 'include_dirs': [ + 'include/', + ], + 'link_settings': { + 'libraries': [ + '