From 39073519b105f91103743e50d34387299162dedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Wed, 25 Nov 2020 00:00:00 +0000 Subject: [PATCH] GoogleTest hello world. ./build and ./test work automatically when cwd is inside userland/libs/XXX without --package-all. --- .gitmodules | 9 ++-- README.adoc | 81 +++++++++++++++++++++++++------ build-userland-in-tree | 15 +++--- common.py | 25 ++++++++-- path_properties.py | 6 +++ submodules/googletest | 1 + test-executables-in-tree | 13 +++-- userland/libs/googletest/build | 1 + userland/libs/googletest/fail.cpp | 9 ++++ userland/libs/googletest/main.cpp | 27 +++++++++++ userland/libs/googletest/test | 1 + 11 files changed, 156 insertions(+), 32 deletions(-) create mode 160000 submodules/googletest create mode 120000 userland/libs/googletest/build create mode 100644 userland/libs/googletest/fail.cpp create mode 100644 userland/libs/googletest/main.cpp create mode 120000 userland/libs/googletest/test diff --git a/.gitmodules b/.gitmodules index 1c9c96d..c24f2ae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,6 +11,9 @@ [submodule "submodules/crosstool-ng"] path = submodules/crosstool-ng url = https://github.com/cirosantilli/crosstool-ng +[submodule "submodules/freebsd"] + path = submodules/freebsd + url = https://github.com/cirosantilli/freebsd [submodule "submodules/gcc"] path = submodules/gcc url = https://github.com/cirosantilli/gcc @@ -30,6 +33,9 @@ # git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # But git clone --branch --depth 1 worked weirdly: # https://unix.stackexchange.com/questions/338578/linux-kernel-source-code-size-difference +[submodule "submodules/googletest"] + path = submodules/googletest + url = https://github.com/cirosantilli/googletest [submodule "submodules/linux"] path = submodules/linux url = https://github.com/cirosantilli/linux @@ -39,6 +45,3 @@ [submodule "submodules/xen"] path = submodules/xen url = https://github.com/cirosantilli/xen -[submodule "submodules/freebsd"] - path = submodules/freebsd - url = https://github.com/cirosantilli/freebsd diff --git a/README.adoc b/README.adoc index ea76d64..c970f47 100644 --- a/README.adoc +++ b/README.adoc @@ -13504,7 +13504,7 @@ Running individual unit tests is not yet exposed, but it is easy to do: while ru so you can just copy paste the command. -Building individual tests is possible with: +Building individual tests is possible with `--unit-test` (singular, no 's'): .... ./build-gem5 --unit-test base/circlebuf.test @@ -20628,6 +20628,62 @@ link:userland/cpp/custom_iterator.cpp[]: there is no way to easily define a nice * https://stackoverflow.com/questions/3582608/how-to-correctly-implement-custom-iterators-and-const-iterators * https://stackoverflow.com/questions/6471019/can-should-i-inherit-from-an-stl-iterator +[[cpp-third-party-libraries]] +==== C++ third-party libraries + +Under: <>. + +===== Boost + +link:https://++en.wikipedia.org/wiki/Boost_(C%2B%2B_libraries)++[] + +link:userland/libs/boost[]: + +* link:userland/libs/boost/bimap.cpp[] + +===== GoogleTest + +https://github.com/google/googletest + +On Ubuntu 20.04, the package: + +.... +sudo apt install googletest +.... + +does not contain prebuilts, and it is intentional, it is incomprehensible: + +* https://askubuntu.com/questions/97626/how-to-install-googletest/1295185#1295185 +* https://askubuntu.com/questions/145887/why-no-library-files-installed-for-google-test + +so you might as well just `git clone` and build the damned thing yourself: + +.... +git submodule update --init submodules/googletest +cd submodules/googletest +mkdir build +cd build +cmake .. +make -j`nproc` +cd ../../userland/libs/googletest +./build +.... + +link:userland/libs/googletest[]: + +* userland/libs/googletest/main.cpp[] + +===== HDF5 + +https://en.wikipedia.org/wiki/Hierarchical_Data_Format + +Binary format to store data. TODO vs databases, notably SQLite: https://datascience.stackexchange.com/questions/262/hierarchical-data-format-what-are-the-advantages-compared-to-alternative-format + +Examples: + +* link:userland/libs/hdf5[] +* gem5 can dump statistics as HDF5: <> + === POSIX Programs under link:userland/posix/[] are examples of POSIX C programming. @@ -21344,24 +21400,19 @@ See for example <>. Since it is located under `userland/libs/openblas`, it ./build-userland --package-all .... -==== Boost +As an exception, if you first `cd` directly into one of the directories and do a <>, e.g.: -link:https://++en.wikipedia.org/wiki/Boost_(C%2B%2B_libraries)++[] +.... +sudo apt install libeigen3-dev +cd userland/libs/eigen +./build +.... -link:userland/libs/boost[] +then that library will be automatically enabled. -* link:userland/libs/boost/bimap.cpp[] +See also: -==== HDF5 - -https://en.wikipedia.org/wiki/Hierarchical_Data_Format - -Binary format to store data. TODO vs databases, notably SQLite: https://datascience.stackexchange.com/questions/262/hierarchical-data-format-what-are-the-advantages-compared-to-alternative-format - -Examples: - -* link:userland/libs/hdf5[] -* gem5 can dump statistics as HDF5: <> +* <> === Userland content filename conventions diff --git a/build-userland-in-tree b/build-userland-in-tree index 472c43f..e75297e 100755 --- a/build-userland-in-tree +++ b/build-userland-in-tree @@ -10,16 +10,19 @@ build_userland = lkmc.import_path.import_path_relative_root('build-userland') class Main(build_userland.Main): def __init__(self): + defaults = { + 'archs': [platform.processor()], + 'gcc_which': 'host', + 'in_tree': True, + 'targets': ['.'], + } + if self.cwd_in_lib(): + defaults['package_all'] = True super().__init__( description='''\ https://cirosantilli.com/linux-kernel-module-cheat#userland-setup-getting-started-natively ''', - defaults={ - 'archs': [platform.processor()], - 'gcc_which': 'host', - 'in_tree': True, - 'targets': ['.'], - } + defaults=defaults ) if __name__ == '__main__': diff --git a/common.py b/common.py index d24586b..384754f 100644 --- a/common.py +++ b/common.py @@ -69,6 +69,8 @@ consts['kernel_modules_subdir'] = 'kernel_modules' consts['kernel_modules_source_dir'] = os.path.join(consts['root_dir'], consts['kernel_modules_subdir']) consts['userland_subdir'] = 'userland' consts['userland_source_dir'] = os.path.join(consts['root_dir'], consts['userland_subdir']) +consts['userland_libs_basename'] = 'libs' +consts['userland_source_libs_dir'] = os.path.join(consts['userland_source_dir'], consts['userland_libs_basename']) consts['userland_source_arch_dir'] = os.path.join(consts['userland_source_dir'], 'arch') consts['userland_executable_ext'] = '.out' consts['baremetal_executable_ext'] = '.elf' @@ -83,6 +85,7 @@ consts['crosstool_ng_supported_archs'] = set(['arm', 'aarch64']) consts['linux_source_dir'] = os.path.join(consts['submodules_dir'], 'linux') consts['linux_config_dir'] = os.path.join(consts['root_dir'], 'linux_config') consts['gem5_default_source_dir'] = os.path.join(consts['submodules_dir'], 'gem5') +consts['googletest_source_dir'] = os.path.join(consts['submodules_dir'], 'googletest') consts['rootfs_overlay_dir'] = os.path.join(consts['root_dir'], 'rootfs_overlay') consts['extract_vmlinux'] = os.path.join(consts['linux_source_dir'], 'scripts', 'extract-vmlinux') consts['qemu_source_dir'] = os.path.join(consts['submodules_dir'], 'qemu') @@ -1358,6 +1361,10 @@ lunch aosp_{}-eng ''' return os.path.join(env['gem5_executable_dir'], name + env['gem5_executable_suffix']) + @staticmethod + def cwd_in_lib(): + return pathlib.Path(common.consts['userland_source_libs_dir']) in pathlib.Path(os.getcwd()).parents + def gem5_list_checkpoint_dirs(self): ''' List checkpoint directory, oldest first. @@ -1896,14 +1903,15 @@ after configure, e.g. SCons. Usually contains specific targets or other build fl '-march={}'.format(self.env['march']), LF, ]) if dirpath_relative_root_components_len > 0: - if dirpath_relative_root_components[0] == 'userland': + if dirpath_relative_root_components[0] == consts['userland_subdir']: if dirpath_relative_root_components_len > 1: - if dirpath_relative_root_components[1] == 'libs': + if dirpath_relative_root_components[1] == self.env['userland_libs_basename']: if dirpath_relative_root_components_len > 1: if self.env['gcc_which'] == 'host': eigen_root = '/' else: eigen_root = self.env['buildroot_staging_dir'] + # TODO move to path_properties.py somehow. packages = { 'boost': { # Header only, no pkg-config package. @@ -1931,6 +1939,17 @@ after configure, e.g. SCons. Usually contains specific targets or other build fl 'hdf5': { 'pkg_config_id': 'hdf5-serial', }, + 'googletest': { + 'cc_flags': [ + '-I', os.path.join(self.env['googletest_source_dir'], 'googletest', 'include'), LF, + '-I', os.path.join(self.env['googletest_source_dir'], 'googlemock', 'include'), LF, + ], + 'cc_flags_after': [ + os.path.join(self.env['googletest_source_dir'], 'build', 'lib', 'libgtest.a'), LF, + os.path.join(self.env['googletest_source_dir'], 'build', 'lib', 'libgtest_main.a'), LF, + os.path.join(self.env['googletest_source_dir'], 'build', 'lib', 'libgmock.a'), LF, + ], + }, } package_key = dirpath_relative_root_components[2] if package_key in packages: @@ -1951,7 +1970,7 @@ after configure, e.g. SCons. Usually contains specific targets or other build fl ]).decode() cc_flags.extend(self.sh.shlex_split(pkg_config_output)) if 'cc_flags_after' in package: - cc_flags.extend(package['cc_flags_after']) + cc_flags_after.extend(package['cc_flags_after']) else: pkg_config_output = subprocess.check_output([ self.env['pkg_config'], diff --git a/path_properties.py b/path_properties.py index 82882c6..73b1242 100644 --- a/path_properties.py +++ b/path_properties.py @@ -749,6 +749,12 @@ path_properties_tuples = ( {'requires_dynamic_library': True}, { 'cython': {'no_build': True}, + 'googletest': ( + {}, + { + 'fail.cpp': {'exit_status': 1}, + } + ), 'libdrm': {'requires_sudo': True}, 'hdf5': ( {}, diff --git a/submodules/googletest b/submodules/googletest new file mode 160000 index 0000000..b1fbd33 --- /dev/null +++ b/submodules/googletest @@ -0,0 +1 @@ +Subproject commit b1fbd33c06cdb0024c67733c6fdec2009d17b384 diff --git a/test-executables-in-tree b/test-executables-in-tree index 0bb5031..8c3b96a 100755 --- a/test-executables-in-tree +++ b/test-executables-in-tree @@ -6,15 +6,18 @@ test_user_mode = lkmc.import_path.import_path_relative_root('test-executables') class Main(test_user_mode.Main): def __init__(self): + defaults = { + 'emulators': ['native'], + 'in_tree': True, + 'tests': ['.'], + } + if self.cwd_in_lib(): + defaults['package_all'] = True super().__init__( description='''\ https://cirosantilli.com/linux-kernel-module-cheat#userland-setup-getting-started-natively ''', - defaults={ - 'emulators': ['native'], - 'in_tree': True, - 'tests': ['.'], - } + defaults=defaults ) if __name__ == '__main__': diff --git a/userland/libs/googletest/build b/userland/libs/googletest/build new file mode 120000 index 0000000..ab18017 --- /dev/null +++ b/userland/libs/googletest/build @@ -0,0 +1 @@ +../build \ No newline at end of file diff --git a/userland/libs/googletest/fail.cpp b/userland/libs/googletest/fail.cpp new file mode 100644 index 0000000..989a640 --- /dev/null +++ b/userland/libs/googletest/fail.cpp @@ -0,0 +1,9 @@ +#include + +TEST(FailTest, ThisTestPasses) { + EXPECT_EQ(1, 1); +} + +TEST(FailTest, ThisTestFails) { + EXPECT_EQ(1, 2); +} diff --git a/userland/libs/googletest/main.cpp b/userland/libs/googletest/main.cpp new file mode 100644 index 0000000..d73d646 --- /dev/null +++ b/userland/libs/googletest/main.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include +#include + +using testing::ElementsAre; +using testing::Pair; + +TEST(MainTest, MyTest0) { + EXPECT_EQ(1, 1); + + // Array comparison. + // https://stackoverflow.com/questions/1460703/comparison-of-arrays-in-google-test + ASSERT_THAT( + (std::vector{5, 10, 15}), + ElementsAre(5, 10, 15) + ); + ASSERT_THAT( + (std::vector>{{1, -1}, {2, -2}}), + ElementsAre(Pair(1, -1), Pair(2, -2)) + ); +} + +TEST(MainTest, MyTest1) { + EXPECT_EQ(1, 1); +} diff --git a/userland/libs/googletest/test b/userland/libs/googletest/test new file mode 120000 index 0000000..419df4f --- /dev/null +++ b/userland/libs/googletest/test @@ -0,0 +1 @@ +../test \ No newline at end of file