Initial project skeleton.
This includes a working gyp-based build of an executable that uses LLVM.
This commit is contained in:
parent
c03f57c8c6
commit
7e4a9220d7
|
@ -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/
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
Names should be added to this file like so: `Name or Organization <email address>`
|
||||||
|
|
||||||
|
* Ben Vanik <ben.vanik@gmail.com>
|
94
README.md
94
README.md
|
@ -15,13 +15,12 @@ Coming soon (maybe):
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
git clone https://github.com/benvanik/xenia.git
|
git clone https://github.com/benvanik/xenia.git
|
||||||
./xenia-build.sh setup
|
cd xenia && source xeniarc
|
||||||
./xenia-build.sh build
|
xb setup
|
||||||
./bin/xenia some.xex
|
xb build
|
||||||
|
./bin/xenia-run some.xex
|
||||||
|
|
||||||
## Building
|
## Requirements
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
You must have a 64-bit machine for building and running the project. Always
|
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
|
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
|
#### 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
|
||||||
|
|
|
@ -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 "$@"
|
|
@ -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 "$@"
|
|
@ -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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -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_
|
|
@ -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 <xenia/xenia.h>
|
||||||
|
|
||||||
|
#include <llvm/IR/DerivedTypes.h>
|
||||||
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
#include <llvm/IR/LLVMContext.h>
|
||||||
|
#include <llvm/IR/Module.h>
|
||||||
|
|
||||||
|
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<Function>(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;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||||
|
{
|
||||||
|
'sources': [
|
||||||
|
'something.cc',
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 12d97efcb0d2cbe321ab6f050c2b2311e7048429
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit b956ec176a23dff2324c4938c3433c5e5ce2eae5
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 8a4c9e05f794162af46939e078ee6464367cafc9
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||||
|
{
|
||||||
|
'includes': [
|
||||||
|
'xenia-info/xenia-info.gypi',
|
||||||
|
'xenia-run/xenia-run.gypi',
|
||||||
|
],
|
||||||
|
}
|
|
@ -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 <xenia/xenia.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return some_function(4);
|
||||||
|
}
|
|
@ -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',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -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 <xenia/xenia.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return some_function(4);
|
||||||
|
}
|
|
@ -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',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -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()
|
|
@ -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': [
|
||||||
|
'<!@(<(llvm_config) --ldflags)',
|
||||||
|
'<!@(<(llvm_config) --libs core)',
|
||||||
|
],
|
||||||
|
'library_dirs': [
|
||||||
|
# NOTE: this doesn't actually do anything...
|
||||||
|
# http://code.google.com/p/gyp/issues/detail?id=130
|
||||||
|
'<!@(<(llvm_config) --libdir)',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'linkflags': [
|
||||||
|
],
|
||||||
|
'libraries': [
|
||||||
|
#'!@(pkg-config --libs-only-l apr-1)',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
'cflags': [
|
||||||
|
'<!@(<(llvm_config) --cxxflags)'
|
||||||
|
],
|
||||||
|
|
||||||
|
'defines': [
|
||||||
|
'__STDC_LIMIT_MACROS=1',
|
||||||
|
'__STDC_CONSTANT_MACROS=1',
|
||||||
|
],
|
||||||
|
|
||||||
|
'include_dirs': [
|
||||||
|
'.',
|
||||||
|
'<!@(<(llvm_config) --includedir)',
|
||||||
|
],
|
||||||
|
|
||||||
|
'includes': [
|
||||||
|
'src/core/sources.gypi',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
Loading…
Reference in New Issue