Skip to content

Commit

Permalink
configure.py: Support --gtest-source-dir to build tests.
Browse files Browse the repository at this point in the history
Allow the Ninja build plan generated by configure.py to
build `ninja_test` by compiling GoogleTest from source if
the path to the library if passed through the new option
`--gtest-source-dir` or the GTEST_SOURCE_DIR environment
variable.

For simplicity, probing for an installed version of the
library, and linking to it, is not supported (use the
CMake build for this).

This also removes the obsolete `--gtest-dir` option.

+ Update README.md

Fixes #2447
  • Loading branch information
digit-google committed May 12, 2024
1 parent c470bf7 commit afcd4a1
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ via CMake. For more details see
This will generate the `ninja` binary and a `build.ninja` file you can now use
to build Ninja with itself.

If you have a GoogleTest source directory, you can build the tests
by passing its path with `--gtest-source-dir=PATH` option, or the
`GTEST_SOURCE_DIR` environment variable, e.g.:

```
./configure.py --bootstrap --gtest-source-dir=/path/to/googletest
./ninja all # build ninja_test and other auxiliary binaries
./ninja_test` # run the unit-test suite.
```

Use the CMake build below if you want to use a preinstalled binary
version of the library.

### CMake

```
Expand Down
83 changes: 82 additions & 1 deletion configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ def _run_command(self, cmdline: str) -> None:
parser.add_option('--profile', metavar='TYPE',
choices=profilers,
help='enable profiling (' + '/'.join(profilers) + ')',)
parser.add_option('--with-gtest', metavar='PATH', help='ignored')
parser.add_option('--gtest-source-dir', metavar='PATH',
help='Path to GoogleTest source directory. If not provided ' +
'GTEST_SOURCE_DIR will be probed in the environment. ' +
'Tests will not be built without a value.')
parser.add_option('--with-python', metavar='EXE',
help='use EXE as the Python interpreter',
default=os.path.basename(sys.executable))
Expand Down Expand Up @@ -435,6 +438,7 @@ def shell_escape(str: str) -> str:
if 'LDFLAGS' in configure_env:
ldflags.append(configure_env['LDFLAGS'])
n.variable('ldflags', ' '.join(shell_escape(flag) for flag in ldflags))

n.newline()

if platform.is_msvc():
Expand Down Expand Up @@ -592,6 +596,83 @@ def has_re2c() -> bool:
# build.ninja file.
n = ninja_writer

# Build the ninja_test executable only if the GTest source directory
# is provided explicitly. Either from the environment with GTEST_SOURCE_DIR
# or with the --gtest-source-dir command-line option.
#
# Do not try to look for an installed binary version, and link against it
# because doing so properly is platform-specific (use the CMake build for
# this).
if options.gtest_source_dir:
gtest_src_dir = options.gtest_source_dir
else:
gtest_src_dir = os.environ.get('GTEST_SOURCE_DIR')

if gtest_src_dir:
# Verify GoogleTest source directory, and add its include directory
# to the global include search path (even for non-test sources) to
# keep the build plan generation simple.
gtest_all_cc = os.path.join(gtest_src_dir, 'googletest', 'src', 'gtest-all.cc')
if not os.path.exists(gtest_all_cc):
print('ERROR: Missing GoogleTest source file: %s' % gtest_all_cc)
sys.exit(1)

n.comment('Tests all build into ninja_test executable.')

# Test-specific version of cflags, must include the GoogleTest
# include directory. Also GoogleTest can only build with a C++14 compiler.
test_cflags = [f.replace('std=c++11', 'std=c++14') for f in cflags]
test_cflags.append('-I' + os.path.join(gtest_src_dir, 'googletest', 'include'))

test_variables = [('cflags', test_cflags)]
if platform.is_msvc():
test_variables += [('pdb', 'ninja_test.pdb')]

test_names = [
'build_log_test',
'build_test',
'clean_test',
'clparser_test',
'depfile_parser_test',
'deps_log_test',
'disk_interface_test',
'dyndep_parser_test',
'edit_distance_test',
'graph_test',
'json_test',
'lexer_test',
'manifest_parser_test',
'ninja_test',
'state_test',
'string_piece_util_test',
'subprocess_test',
'test',
'util_test',
]
if platform.is_windows():
test_names += [
'includes_normalize_test',
'msvc_helper_test',
]

objs = []
for name in test_names:
objs += cxx(name, variables=test_variables)

# Build GTest as a monolithic source file.
# This requires one extra include search path, so replace the
# value of 'cflags' in our list.
gtest_all_variables = test_variables[1:] + [
('cflags', test_cflags + ['-I' + os.path.join(gtest_src_dir, 'googletest') ]),
]
# Do not use cxx() directly to ensure the object file is under $builddir.
objs += n.build(built('gtest_all' + objext), 'cxx', gtest_all_cc, variables=gtest_all_variables)

ninja_test = n.build(binary('ninja_test'), 'link', objs, implicit=ninja_lib,
variables=[('libs', libs)])
n.newline()
all_targets += ninja_test

n.comment('Ancillary executables.')

if platform.is_aix() and '-maix64' not in ldflags:
Expand Down

0 comments on commit afcd4a1

Please sign in to comment.