Skip to content

Commit

Permalink
version 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
evmar committed Dec 29, 2012
2 parents 7096bf1 + 3249938 commit 2c953d1
Show file tree
Hide file tree
Showing 46 changed files with 1,239 additions and 526 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ TAGS
/doc/manual.html
/doc/doxygen
/gtest-1.6.0

# Eclipse project files
.project
.cproject

7 changes: 7 additions & 0 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,15 @@ it's locked while in use.

### Via mingw on Linux (not well supported)

Setup on Ubuntu Lucid:
* `sudo apt-get install gcc-mingw32 wine`
* `export CC=i586-mingw32msvc-cc CXX=i586-mingw32msvc-c++ AR=i586-mingw32msvc-ar`

Setup on Ubuntu Precise:
* `sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 wine`
* `export CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ AR=i686-w64-mingw32-ar`

Then run:
* `./configure.py --platform=mingw --host=linux`
* Build `ninja.exe` using a Linux ninja binary: `/path/to/linux/ninja`
* Run: `./ninja.exe` (implicitly runs through wine(!))
Expand Down
39 changes: 25 additions & 14 deletions bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function

from optparse import OptionParser
import sys
import os
Expand All @@ -29,6 +31,10 @@
help='enable verbose build',)
parser.add_option('--x64', action='store_true',
help='force 64-bit build (Windows)',)
# TODO: make this --platform to match configure.py.
parser.add_option('--windows', action='store_true',
help='force native Windows build (when using Cygwin Python)',
default=sys.platform.startswith('win32'))
(options, conf_args) = parser.parse_args()

def run(*args, **kwargs):
Expand All @@ -44,11 +50,12 @@ def run(*args, **kwargs):
cflags.append('-I/usr/local/include')
ldflags.append('-L/usr/local/lib')

print 'Building ninja manually...'
print('Building ninja manually...')

try:
os.mkdir('build')
except OSError, e:
except OSError:
e = sys.exc_info()[1]
if e.errno != errno.EEXIST:
raise

Expand All @@ -63,7 +70,7 @@ def run(*args, **kwargs):
if filename == 'browse.cc': # Depends on generated header.
continue

if sys.platform.startswith('win32'):
if options.windows:
if src.endswith('-posix.cc'):
continue
else:
Expand All @@ -72,7 +79,7 @@ def run(*args, **kwargs):

sources.append(src)

if sys.platform.startswith('win32'):
if options.windows:
sources.append('src/getopt.c')

vcdir = os.environ.get('VCINSTALLDIR')
Expand All @@ -87,14 +94,14 @@ def run(*args, **kwargs):
cflags.extend(['-Wno-deprecated',
'-DNINJA_PYTHON="' + sys.executable + '"',
'-DNINJA_BOOTSTRAP'])
if sys.platform.startswith('win32'):
if options.windows:
cflags.append('-D_WIN32_WINNT=0x0501')
if options.x64:
cflags.append('-m64')
args.extend(cflags)
args.extend(ldflags)
binary = 'ninja.bootstrap'
if sys.platform.startswith('win32'):
if options.windows:
binary = 'ninja.bootstrap.exe'
args.extend(sources)
if vcdir:
Expand All @@ -103,16 +110,20 @@ def run(*args, **kwargs):
args.extend(['-o', binary])

if options.verbose:
print ' '.join(args)
print(' '.join(args))

run(args)
try:
run(args)
except:
print('Failure running:', args)
raise

verbose = []
if options.verbose:
verbose = ['-v']

if sys.platform.startswith('win32'):
print 'Building ninja using itself...'
if options.windows:
print('Building ninja using itself...')
run([sys.executable, 'configure.py', '--with-ninja=%s' % binary] +
conf_args)
run(['./' + binary] + verbose)
Expand All @@ -124,17 +135,17 @@ def run(*args, **kwargs):
for obj in glob.glob('*.obj'):
os.unlink(obj)

print """
print("""
Done!
Note: to work around Windows file locking, where you can't rebuild an
in-use binary, to run ninja after making any changes to build ninja itself
you should run ninja.bootstrap instead. Your build is also configured to
use ninja.bootstrap.exe as the MSVC helper; see the --with-ninja flag of
the --help output of configure.py."""
the --help output of configure.py.""")
else:
print 'Building ninja using itself...'
print('Building ninja using itself...')
run([sys.executable, 'configure.py'] + conf_args)
run(['./' + binary] + verbose)
os.unlink(binary)
print 'Done!'
print('Done!')
56 changes: 27 additions & 29 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
Projects that use ninja themselves should either write a similar script
or use a meta-build system that supports Ninja output."""

from __future__ import print_function

from optparse import OptionParser
import os
import sys
Expand Down Expand Up @@ -50,7 +52,7 @@
default="ninja")
(options, args) = parser.parse_args()
if args:
print 'ERROR: extra unparsed command-line arguments:', args
print('ERROR: extra unparsed command-line arguments:', args)
sys.exit(1)

platform = options.platform
Expand Down Expand Up @@ -140,6 +142,7 @@ def binary(name):
'-fno-rtti',
'-fno-exceptions',
'-fvisibility=hidden', '-pipe',
'-Wno-missing-field-initializers',
'-DNINJA_PYTHON="%s"' % options.with_python]
if options.debug:
cflags += ['-D_GLIBCXX_DEBUG', '-D_GLIBCXX_DEBUG_PEDANTIC']
Expand Down Expand Up @@ -168,7 +171,9 @@ def binary(name):
libs.append('-lprofiler')

def shell_escape(str):
"""Escape str such that it's interpreted as a single argument by the shell."""
"""Escape str such that it's interpreted as a single argument by
the shell."""

# This isn't complete, but it's just enough to make NINJA_PYTHON work.
if platform in ('windows', 'mingw'):
return str
Expand Down Expand Up @@ -255,7 +260,7 @@ def has_re2c():
n.build(src('depfile_parser.cc'), 're2c', src('depfile_parser.in.cc'))
n.build(src('lexer.cc'), 're2c', src('lexer.in.cc'))
else:
print ("warning: A compatible version of re2c (>= 0.11.3) was not found; "
print("warning: A compatible version of re2c (>= 0.11.3) was not found; "
"changes to src/*.in.cc will not affect your build.")
n.newline()

Expand All @@ -277,11 +282,12 @@ def has_re2c():
'util']:
objs += cxx(name)
if platform in ('mingw', 'windows'):
objs += cxx('subprocess-win32')
for name in ['subprocess-win32',
'includes_normalize-win32',
'msvc_helper-win32',
'msvc_helper_main-win32']:
objs += cxx(name)
if platform == 'windows':
objs += cxx('includes_normalize-win32')
objs += cxx('msvc_helper-win32')
objs += cxx('msvc_helper_main-win32')
objs += cxx('minidump-win32')
objs += cc('getopt')
else:
Expand Down Expand Up @@ -309,7 +315,7 @@ def has_re2c():
n.comment('Tests all build into ninja_test executable.')

variables = []
test_cflags = None
test_cflags = cflags[:]
test_ldflags = None
test_libs = libs
objs = []
Expand All @@ -328,13 +334,17 @@ def has_re2c():
os.path.join(path, 'src', 'gtest_main.cc'),
variables=[('cflags', gtest_cflags)])

test_cflags = cflags + ['-DGTEST_HAS_RTTI=0',
'-I%s' % os.path.join(path, 'include')]
test_cflags.append('-I%s' % os.path.join(path, 'include'))
elif platform == 'windows':
test_libs.extend(['gtest_main.lib', 'gtest.lib'])
else:
test_cflags.append('-DGTEST_HAS_RTTI=0')
test_libs.extend(['-lgtest_main', '-lgtest'])

if test_cflags == cflags:
test_cflags = None

n.variable('test_cflags', test_cflags)
for name in ['build_log_test',
'build_test',
'clean_test',
Expand All @@ -348,8 +358,8 @@ def has_re2c():
'subprocess_test',
'test',
'util_test']:
objs += cxx(name, variables=[('cflags', test_cflags)])
if platform == 'windows':
objs += cxx(name, variables=[('cflags', '$test_cflags')])
if platform in ('windows', 'mingw'):
for name in ['includes_normalize_test', 'msvc_helper_test']:
objs += cxx(name, variables=[('cflags', test_cflags)])

Expand All @@ -362,7 +372,7 @@ def has_re2c():
all_targets += ninja_test


n.comment('Ancilliary executables.')
n.comment('Ancillary executables.')
objs = cxx('parser_perftest')
all_targets += n.build(binary('parser_perftest'), 'link', objs,
implicit=ninja_lib, variables=[('libs', libs)])
Expand Down Expand Up @@ -427,23 +437,11 @@ def has_re2c():
if host == 'linux':
n.comment('Packaging')
n.rule('rpmbuild',
command="rpmbuild \
--define 'ver git' \
--define \"rel `git rev-parse --short HEAD`\" \
--define '_topdir %(pwd)/rpm-build' \
--define '_builddir %{_topdir}' \
--define '_rpmdir %{_topdir}' \
--define '_srcrpmdir %{_topdir}' \
--define '_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm' \
--define '_specdir %{_topdir}' \
--define '_sourcedir %{_topdir}' \
--quiet \
-bb misc/packaging/ninja.spec",
description='Building RPM..')
n.build('rpm', 'rpmbuild',
implicit=['ninja','README', 'COPYING', doc('manual.html')])
command="misc/packaging/rpmbuild.sh",
description='Building rpms..')
n.build('rpm', 'rpmbuild')
n.newline()

n.build('all', 'phony', all_targets)

print 'wrote %s.' % BUILD_FILENAME
print('wrote %s.' % BUILD_FILENAME)
54 changes: 54 additions & 0 deletions doc/manual.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ Ninja supports one environment variable to control its behavior.
Several placeholders are available:
* `%s`: The number of started edges.
* `%t`: The total number of edges that must be run to complete the build.
* `%p`: The percentage of started edges.
* `%r`: The number of currently running edges.
* `%u`: The number of remaining edges to start.
* `%f`: The number of finished edges.
Expand Down Expand Up @@ -420,6 +421,59 @@ If the top-level Ninja file is specified as an output of any build
statement and it is out of date, Ninja will rebuild and reload it
before building the targets requested by the user.
Pools
~~~~~
Pools allow you to allocate one or more rules or edges a finite number
of concurrent jobs which is more tightly restricted than the default
parallelism.
This can be useful, for example, to restrict a particular expensive rule
(like link steps for huge executables), or to restrict particular build
statements which you know perform poorly when run concurrently.
Each pool has a `depth` variable which is specified in the build file.
The pool is then referred to with the `pool` variable on either a rule
or a build statement.
No matter what pools you specify, ninja will never run more concurrent jobs
than the default parallelism, or the number of jobs specified on the command
line (with -j).
----------------
# No more than 4 links at a time.
pool link_pool
depth = 4
# No more than 1 heavy object at a time.
pool heavy_object_pool
depth = 1
rule link
...
pool = link_pool
rule cc
...
# The link_pool is used here. Only 4 links will run concurrently.
build foo.exe: link input.obj
# A build statement can be exempted from its rule's pool by setting an
# empty pool. This effectively puts the build statement back into the default
# pool, which has infinite depth.
build other.exe: link input.obj
pool =
# A build statement can specify a pool directly.
# Only one of these builds will run at a time.
build heavy_object1.obj: cc heavy_obj1.cc
pool = heavy_object_pool
build heavy_object2.obj: cc heavy_obj2.cc
pool = heavy_object_pool
----------------
Generating Ninja files from code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
12 changes: 10 additions & 2 deletions misc/bash-completion
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@
# . path/to/ninja/misc/bash-completion

_ninja_target() {
local cur targets
local cur targets dir line targets_command OPTIND
cur="${COMP_WORDS[COMP_CWORD]}"
targets=$((ninja -t targets all 2>/dev/null) | awk -F: '{print $1}')
dir="."
line=$(echo ${COMP_LINE} | cut -d" " -f 2-)
while getopts C: opt "${line[@]}"; do
case $opt in
C) dir="$OPTARG" ;;
esac
done;
targets_command="ninja -C ${dir} -t targets all"
targets=$((${targets_command} 2>/dev/null) | awk -F: '{print $1}')
COMPREPLY=($(compgen -W "$targets" -- "$cur"))
return 0
}
Expand Down
3 changes: 2 additions & 1 deletion misc/ninja-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
(setq ninja-keywords
(list
'("^#.*" . font-lock-comment-face)
(cons (concat "^" (regexp-opt '("rule" "build" "subninja" "include")
(cons (concat "^" (regexp-opt '("rule" "build" "subninja" "include"
"pool" "default")
'words))
font-lock-keyword-face)
'("\\([[:alnum:]_]+\\) =" . (1 font-lock-variable-name-face))
Expand Down
Loading

0 comments on commit 2c953d1

Please sign in to comment.