cc_project_template_gn

A gn, ninja, and googletest-based C++ project template
git clone https://git.bracken.jp/cc_project_template_gn.git
Log | Files | Refs | Submodules | README | LICENSE

commit ffd0fb7ed3e9202cf87094653878b5ae4e65a74e
Author: Chris Bracken <chris@bracken.jp>
Date:   Sat,  7 Apr 2018 11:57:50 -0700

Initial commit

Diffstat:
A.clang-format | 12++++++++++++
A.gitignore | 1+
A.gitmodules | 3+++
A.gn | 7+++++++
ABUILD.gn | 5+++++
ALICENSE | 27+++++++++++++++++++++++++++
AREADME.md | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asecondary/third_party/googletest/BUILD.gn | 422+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/BUILD.gn | 31+++++++++++++++++++++++++++++++
Asrc/bar.cc | 6++++++
Asrc/bar.h | 6++++++
Asrc/bar_test.cc | 16++++++++++++++++
Asrc/foo.cc | 5+++++
Asrc/foo.h | 6++++++
Asrc/foo_test.cc | 15+++++++++++++++
Asrc/main.cc | 13+++++++++++++
Athird_party/googletest | 1+
17 files changed, 635 insertions(+), 0 deletions(-)

diff --git a/.clang-format b/.clang-format @@ -0,0 +1,12 @@ +# Defines the Chromium style for automatic reformatting. +# http://clang.llvm.org/docs/ClangFormatStyleOptions.html +BasedOnStyle: Chromium +# This defaults to 'Auto'. Explicitly set it for a while, so that +# 'vector<vector<int> >' in existing files gets formatted to +# 'vector<vector<int>>'. ('Auto' means that clang-format will only use +# 'int>>' if the file already contains at least one such instance.) +Standard: Cpp11 +SortIncludes: true +--- +Language: ObjC +ColumnLimit: 100 diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +out/ diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "third_party/googletest"] + path = third_party/googletest + url = git@github.com:google/googletest.git diff --git a/.gn b/.gn @@ -0,0 +1,7 @@ +# The location of the build configuration file. +buildconfig = "//build/BUILDCONFIG.gn" + +# The secondary source root is a parallel directory tree where GN build files +# are placed when they can not be placed directly in the source tree, e.g. for +# third party source trees. +secondary_source = "//secondary/" diff --git a/BUILD.gn b/BUILD.gn @@ -0,0 +1,5 @@ +group("default") { + deps = [ + "//src:main", + ] +} diff --git a/LICENSE b/LICENSE @@ -0,0 +1,27 @@ +Copyright 2018 Chris Bracken. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md @@ -0,0 +1,59 @@ +ProjectTemplate +=============== + +A [gn](https://gn.googlesource.com/gn), +[ninja](https://github.com/ninja-build/ninja), and +[googletest](https://github.com/google/googletest)-based C++ project template. + + +Prerequisites +------------- + +To build, you'll need [gn](https://gn.googlesource.com/gn), +[ninja](https://github.com/ninja-build/ninja), and a clang build toolchain +installed on your system. + + +Obtaining the source +-------------------- + +First, clone the repo. Then, initialise and fetch git submodules: + + # Initialise local configuration file. + git submodule init + + # Fetch data from the buildroot submodule. + git submodule update + + +Updating the gn buildroot +------------------------- + +To update the git submodules to a newer commit, simply run: + + git submodule update --remote + + +Building and running +-------------------- + +First, generate the ninja build files under the `out` directory: + + gn gen --args=is_debug=true out/debug + gn gen --args=is_debug=false out/release + + +### Unit tests + +To build and run the unit tests, run: + + ninja -C out/debug src:foo_tests + ./out/debug/foo_tests + + +### Executable binary + +To build and run the binary: + + ninja -C out/debug src:foo + ./out/debug/main diff --git a/secondary/third_party/googletest/BUILD.gn b/secondary/third_party/googletest/BUILD.gn @@ -0,0 +1,422 @@ +config("gtest_private_config") { + visibility = [ ":*" ] + include_dirs = [ "googletest" ] + cflags_cc = [ + "-Wno-covered-switch-default", + "-Wno-deprecated", + "-Wno-double-promotion", + "-Wno-exit-time-destructors", + "-Wno-float-equal", + "-Wno-gnu-zero-variadic-macro-arguments", + "-Wno-missing-prototypes", + "-Wno-missing-variable-declarations", + "-Wno-old-style-cast", + "-Wno-sign-conversion", + "-Wno-switch-enum", + "-Wno-unreachable-code-break", + "-Wno-unused-member-function", + "-Wno-unused-private-field", + "-Wno-unused-template", + "-Wno-used-but-marked-unused", + "-Wno-zero-as-null-pointer-constant", + ] + ldflags = ["-lpthread"] +} + +config("gtest_config") { + include_dirs = [ "googletest/include" ] + cflags_cc = [ + "-Wno-global-constructors", + "-Wno-missing-noreturn", + "-Wno-padded", + "-Wno-shift-sign-overflow", + "-Wno-thread-safety", # googletest lacks locking annotations. + "-Wno-undef", + "-Wno-weak-vtables", + ] + ldflags = ["-lpthread"] +} + +source_set("gtest_internal_headers") { + visibility = [ ":*" ] + testonly = true + sources = [ + "googletest/include/gtest/gtest-death-test.h", + "googletest/include/gtest/gtest-message.h", + "googletest/include/gtest/gtest-param-test.h", + "googletest/include/gtest/gtest-printers.h", + "googletest/include/gtest/gtest-test-part.h", + "googletest/include/gtest/gtest-typed-test.h", + "googletest/include/gtest/gtest_pred_impl.h", + "googletest/include/gtest/gtest_prod.h", + "googletest/include/gtest/internal/custom/gtest-port.h", + "googletest/include/gtest/internal/custom/gtest-printers.h", + "googletest/include/gtest/internal/custom/gtest.h", + "googletest/include/gtest/internal/gtest-death-test-internal.h", + "googletest/include/gtest/internal/gtest-filepath.h", + "googletest/include/gtest/internal/gtest-internal.h", + "googletest/include/gtest/internal/gtest-linked_ptr.h", + "googletest/include/gtest/internal/gtest-param-util-generated.h", + "googletest/include/gtest/internal/gtest-param-util.h", + "googletest/include/gtest/internal/gtest-port-arch.h", + "googletest/include/gtest/internal/gtest-port.h", + "googletest/include/gtest/internal/gtest-string.h", + "googletest/include/gtest/internal/gtest-tuple.h", + "googletest/include/gtest/internal/gtest-type-util.h", + "googletest/src/gtest-internal-inl.h", + ] +} + +source_set("gtest_test_headers") { + visibility = [ ":*" ] + testonly = true + sources = [ + "googletest/include/gtest/gtest-spi.h", + ] +} + +static_library("gtest") { + testonly = true + public = [ + "googletest/include/gtest/gtest.h", + ] + sources = [ + "googletest/src/gtest-all.cc", + "googletest/src/gtest-death-test.cc", + "googletest/src/gtest-filepath.cc", + "googletest/src/gtest-port.cc", + "googletest/src/gtest-printers.cc", + "googletest/src/gtest-test-part.cc", + "googletest/src/gtest-typed-test.cc", + "googletest/src/gtest.cc", + ] + sources -= [ "googletest/src/gtest-all.cc" ] + public_configs = [ ":gtest_config" ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest_internal_headers", + ":gtest_test_headers", + ] +} + +static_library("gtest_main") { + testonly = true + sources = [ + "googletest/src/gtest_main.cc", + ] + public_deps = [ + ":gtest", + ] +} + +executable("gtest_all_test") { + testonly = true + sources = [ + "googletest/test/googletest-death-test-test.cc", + "googletest/test/googletest-filepath-test.cc", + "googletest/test/googletest-linked-ptr-test.cc", + "googletest/test/googletest-message-test.cc", + "googletest/test/googletest-options-test.cc", + "googletest/test/googletest-port-test.cc", + "googletest/test/googletest-printers-test.cc", + "googletest/test/googletest-test-part-test.cc", + "googletest/test/gtest-typed-test2_test.cc", + "googletest/test/gtest-typed-test_test.cc", + "googletest/test/gtest-typed-test_test.h", + "googletest/test/gtest_main_unittest.cc", + "googletest/test/gtest_pred_impl_unittest.cc", + "googletest/test/gtest_prod_test.cc", + "googletest/test/gtest_unittest.cc", + "googletest/test/production.cc", + "googletest/test/production.h", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ":gtest_internal_headers", + ":gtest_main", + ":gtest_test_headers", + ] +} + +executable("gtest_environment_test") { + testonly = true + sources = [ + "googletest/test/gtest_environment_test.cc", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ":gtest_internal_headers", + ] +} + +executable("gtest_listener_test") { + testonly = true + sources = [ + "googletest/test/googletest-listener-test.cc", + ] + deps = [ + ":gtest", + ] + cflags_cc = [ + "-Wno-missing-prototypes", + "-Wno-missing-variable-declarations", + ] +} + +executable("gtest_no_test") { + testonly = true + sources = [ + "googletest/test/gtest_no_test_unittest.cc", + ] + deps = [ + ":gtest", + ] +} + +executable("gtest_param_test") { + testonly = true + sources = [ + "googletest/test/googletest-param-test2-test.cc", + "googletest/test/googletest-param-test-test.cc", + "googletest/test/googletest-param-test-test.h", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ] +} + +executable("gtest_premature_exit_test") { + testonly = true + sources = [ + "googletest/test/gtest_premature_exit_test.cc", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ] +} + +executable("gtest_repeat_test") { + testonly = true + sources = [ + "googletest/test/gtest_repeat_test.cc", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ":gtest_internal_headers", + ] +} + +executable("gtest_sole_header_test") { + testonly = true + sources = [ + "googletest/test/gtest_sole_header_test.cc", + ] + deps = [ + ":gtest", + ":gtest_main", + ] +} + +executable("gtest_stress_test") { + testonly = true + sources = [ + "googletest/test/gtest_stress_test.cc", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ":gtest_internal_headers", + ] +} + +executable("gtest_unittest_api_test") { + testonly = true + sources = [ + "googletest/test/gtest-unittest-api_test.cc", + ] + configs += [ ":gtest_private_config" ] + deps = [ + ":gtest", + ] +} + +group("gtest_all_tests") { + testonly = true + deps = [ + ":gtest_all_test", + ":gtest_environment_test", + ":gtest_listener_test", + ":gtest_no_test", + ":gtest_param_test", + ":gtest_premature_exit_test", + ":gtest_repeat_test", + ":gtest_sole_header_test", + ":gtest_stress_test", + ":gtest_unittest_api_test", + ] +} + +config("gmock_private_config") { + visibility = [ ":*" ] + include_dirs = [ "googlemock" ] + cflags_cc = [ + "-Wno-deprecated", + "-Wno-double-promotion", + "-Wno-exit-time-destructors", + "-Wno-float-equal", + "-Wno-missing-prototypes", + "-Wno-pedantic", + "-Wno-sign-conversion", + "-Wno-switch-enum", + "-Wno-unused-macros", + "-Wno-unused-parameter", + "-Wno-used-but-marked-unused", + "-Wno-zero-as-null-pointer-constant", + ] +} + +config("gmock_config") { + include_dirs = [ "googlemock/include" ] + + cflags_cc = [ + # The MOCK_METHODn() macros do not specify "override", which triggers this + # warning in users: "error: 'Method' overrides a member function but is not + # marked 'override' [-Werror,-Winconsistent-missing-override]". Suppress + # these warnings until https://github.com/google/googletest/issues/533 is + # fixed. + "-Wno-inconsistent-missing-override", + ] + ldflags = [ "-lpthread" ] +} + +source_set("gmock_internal_headers") { + visibility = [ ":*" ] + testonly = true + sources = [ + "googlemock/include/gmock/gmock-actions.h", + "googlemock/include/gmock/gmock-cardinalities.h", + "googlemock/include/gmock/gmock-generated-actions.h", + "googlemock/include/gmock/gmock-generated-function-mockers.h", + "googlemock/include/gmock/gmock-generated-matchers.h", + "googlemock/include/gmock/gmock-generated-nice-strict.h", + "googlemock/include/gmock/gmock-matchers.h", + "googlemock/include/gmock/gmock-more-actions.h", + "googlemock/include/gmock/gmock-more-matchers.h", + "googlemock/include/gmock/gmock-spec-builders.h", + "googlemock/include/gmock/internal/custom/gmock-generated-actions.h", + "googlemock/include/gmock/internal/custom/gmock-matchers.h", + "googlemock/include/gmock/internal/custom/gmock-port.h", + "googlemock/include/gmock/internal/gmock-generated-internal-utils.h", + "googlemock/include/gmock/internal/gmock-internal-utils.h", + "googlemock/include/gmock/internal/gmock-port.h", + ] +} + +static_library("gmock") { + testonly = true + public = [ + "googlemock/include/gmock/gmock.h", + ] + sources = [ + "googlemock/src/gmock-all.cc", + "googlemock/src/gmock-cardinalities.cc", + "googlemock/src/gmock-internal-utils.cc", + "googlemock/src/gmock-matchers.cc", + "googlemock/src/gmock-spec-builders.cc", + "googlemock/src/gmock.cc", + ] + sources -= [ "googlemock/src/gmock-all.cc" ] + public_configs = [ ":gmock_config" ] + configs += [ ":gmock_private_config" ] + deps = [ + ":gmock_internal_headers", + ":gtest", + ":gtest_internal_headers", + ] +} + +static_library("gmock_main") { + testonly = true + sources = [ + "googlemock/src/gmock_main.cc", + ] + configs += [ ":gmock_private_config" ] + public_deps = [ + ":gmock", + ":gtest", + ] +} + +executable("gmock_all_test") { + testonly = true + sources = [ + "googlemock/test/gmock-actions_test.cc", + "googlemock/test/gmock-cardinalities_test.cc", + "googlemock/test/gmock-generated-actions_test.cc", + "googlemock/test/gmock-generated-function-mockers_test.cc", + "googlemock/test/gmock-generated-internal-utils_test.cc", + "googlemock/test/gmock-generated-matchers_test.cc", + "googlemock/test/gmock-internal-utils_test.cc", + "googlemock/test/gmock-matchers_test.cc", + "googlemock/test/gmock-more-actions_test.cc", + "googlemock/test/gmock-nice-strict_test.cc", + "googlemock/test/gmock-port_test.cc", + "googlemock/test/gmock-spec-builders_test.cc", + "googlemock/test/gmock_test.cc", + ] + configs += [ + ":gmock_private_config", + ":gtest_private_config", + ] + deps = [ + ":gmock", + ":gmock_internal_headers", + ":gmock_main", + ":gtest", + ":gtest_internal_headers", + ":gtest_test_headers", + ] +} + +executable("gmock_link_test") { + testonly = true + sources = [ + "googlemock/test/gmock_link2_test.cc", + "googlemock/test/gmock_link_test.cc", + "googlemock/test/gmock_link_test.h", + ] + configs += [ ":gmock_private_config" ] + deps = [ + ":gmock", + ":gmock_main", + ":gtest", + ":gtest_internal_headers", + ] +} + +executable("gmock_stress_test") { + testonly = true + sources = [ + "googlemock/test/gmock_stress_test.cc", + ] + cflags_cc = [ "-Wno-unused-member-function" ] + configs += [ ":gmock_private_config" ] + deps = [ + ":gmock", + ":gtest", + ] +} + +group("gmock_all_tests") { + testonly = true + deps = [ + ":gmock_all_test", + ":gmock_link_test", + ":gmock_stress_test", + ] +} diff --git a/src/BUILD.gn b/src/BUILD.gn @@ -0,0 +1,31 @@ +executable("main") { + sources = [ + "main.cc", + ] + deps = [ + ":foo_srcs", + ] +} + +source_set("foo_srcs") { + sources = [ + "bar.cc", + "bar.h", + "foo.cc", + "foo.h", + ] +} + +executable("foo_tests") { + testonly = true + + sources = [ + "bar_test.cc", + "foo_test.cc", + ] + deps = [ + ":foo_srcs", + "//third_party/googletest:gtest", + "//third_party/googletest:gtest_main", + ] +} diff --git a/src/bar.cc b/src/bar.cc @@ -0,0 +1,6 @@ +#include "bar.h" + +int Bar(int x) { + return x - 1; +} + diff --git a/src/bar.h b/src/bar.h @@ -0,0 +1,6 @@ +#ifndef PROJNAME_BAR_H_ +#define PROJNAME_BAR_H_ + +int Bar(int x); + +#endif // PROJNAME_BAR_H_ diff --git a/src/bar_test.cc b/src/bar_test.cc @@ -0,0 +1,16 @@ +#include "bar.h" + +#include "gtest/gtest.h" + +TEST(Bar, DecrementsZero) { + EXPECT_EQ(-1, Bar(0)); +} + +TEST(Bar, DecrementsPositive) { + EXPECT_EQ(1, Bar(2)); +} + +TEST(Bar, DecrementsNegative) { + EXPECT_EQ(-2, Bar(-1)); +} + diff --git a/src/foo.cc b/src/foo.cc @@ -0,0 +1,5 @@ +#include "foo.h" + +int Foo(int x) { + return x + 1; +} diff --git a/src/foo.h b/src/foo.h @@ -0,0 +1,6 @@ +#ifndef PROJNAME_FOO_H_ +#define PROJNAME_FOO_H_ + +int Foo(int x); + +#endif // PROJNAME_FOO_H_ diff --git a/src/foo_test.cc b/src/foo_test.cc @@ -0,0 +1,15 @@ +#include "foo.h" + +#include "gtest/gtest.h" + +TEST(Foo, IncrementsZero) { + EXPECT_EQ(1, Foo(0)); +} + +TEST(Foo, IncrementsPositive) { + EXPECT_EQ(2, Foo(1)); +} + +TEST(Foo, IncrementsNegative) { + EXPECT_EQ(-1, Foo(-2)); +} diff --git a/src/main.cc b/src/main.cc @@ -0,0 +1,13 @@ +#include <iostream> + +#include "foo.h" +#include "bar.h" + +int main(int argc, char** argv) { + for (auto i = 0; i < argc; ++i) + std::cout << "argv[" << i << "]: " << argv[i] << std::endl; + + auto x = Foo(3); + auto y = Bar(x); + std::cout << "x=" << x << ",y=" << y << std::endl; +} diff --git a/third_party/googletest b/third_party/googletest @@ -0,0 +1 @@ +Subproject commit 40f82ce56a4b416aa4631e48d1d07377793b18ee