From d177d6d6dd50093a8328d2658c7a394ee3f441d1 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Wed, 31 Jul 2019 10:03:21 -0400 Subject: [PATCH 01/19] Added spanner/internal/build_info.cc.in and friends --- ci/kokoro/docker/build-in-docker-cmake.sh | 6 +- ci/kokoro/docker/build.sh | 5 + google/cloud/spanner/BUILD | 24 ++++- google/cloud/spanner/CMakeLists.txt | 62 ++++++++++++ .../cloud/spanner/internal/build_info.cc.in | 94 +++++++++++++++++++ google/cloud/spanner/internal/build_info.h | 47 ++++++++++ .../cloud/spanner/internal/build_info_test.cc | 63 +++++++++++++ google/cloud/spanner/spanner_client.bzl | 1 + .../spanner/spanner_client_unit_tests.bzl | 1 + .../cloud/spanner/spanner_client_version.bzl | 19 ++++ 10 files changed, 316 insertions(+), 6 deletions(-) create mode 100644 google/cloud/spanner/internal/build_info.cc.in create mode 100644 google/cloud/spanner/internal/build_info.h create mode 100644 google/cloud/spanner/internal/build_info_test.cc create mode 100644 google/cloud/spanner/spanner_client_version.bzl diff --git a/ci/kokoro/docker/build-in-docker-cmake.sh b/ci/kokoro/docker/build-in-docker-cmake.sh index 41c1ed07..8b1952df 100755 --- a/ci/kokoro/docker/build-in-docker-cmake.sh +++ b/ci/kokoro/docker/build-in-docker-cmake.sh @@ -53,15 +53,11 @@ if [[ "${GOOGLE_CLOUD_CPP_CXX_STANDARD:-}" != "" ]]; then "-DGOOGLE_CLOUD_CPP_CXX_STANDARD=${GOOGLE_CLOUD_CPP_CXX_STANDARD}") fi -if [[ "${CODE_COVERAGE:-}" == "yes" ]]; then - cmake_flags+=( - "-DCMAKE_BUILD_TYPE=Coverage") -fi - # We disable the shellcheck warning because we want ${CMAKE_FLAGS} to expand as # separate arguments. # shellcheck disable=SC2086 cmake "-DCMAKE_INSTALL_PREFIX=$HOME/staging" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ ${CMAKE_FLAGS:-} \ "-H${SOURCE_DIR}" "-B${BINARY_DIR}" "${cmake_flags[@]}" cmake --build "${BINARY_DIR}" -- -j "$(nproc)" diff --git a/ci/kokoro/docker/build.sh b/ci/kokoro/docker/build.sh index 8b5b6901..39a091c6 100755 --- a/ci/kokoro/docker/build.sh +++ b/ci/kokoro/docker/build.sh @@ -52,6 +52,7 @@ if [[ "${BUILD_NAME}" = "clang-tidy" ]]; then export DISTRO_VERSION=30 export CC=clang export CXX=clang++ + export BUILD_TYPE=Debug export CHECK_STYLE=yes export GENERATE_DOCS=yes export CLANG_TIDY=yes @@ -118,6 +119,7 @@ elif [[ "${BUILD_NAME}" = "cxx17" ]]; then export CXX=g++ in_docker_script="ci/kokoro/docker/build-in-docker-cmake.sh" elif [[ "${BUILD_NAME}" = "coverage" ]]; then + export BUILD_TYPE=Coverage export CODE_COVERAGE=yes export RUN_INTEGRATION_TESTS=yes export DISTRO=fedora-install @@ -234,6 +236,9 @@ docker_flags=( # If set, pass -DGOOGLE_CLOUD_CPP_CXX_STANDARD= to CMake. "--env" "GOOGLE_CLOUD_CPP_CXX_STANDARD=${GOOGLE_CLOUD_CPP_CXX_STANDARD:-}" + # The type of the build for CMake + "--env" "BUILD_TYPE=${BUILD_TYPE:-Release}" + # Additional flags to enable CMake features. "--env" "CMAKE_FLAGS=${CMAKE_FLAGS:-}" diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index 1dd55786..b50e6b7d 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -16,11 +16,33 @@ package(default_visibility = ["//visibility:public"]) licenses(["notice"]) # Apache 2.0 +load(":spanner_client_version.bzl", "GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE") + +genrule( + name = "generate_build_info", + srcs = ["internal/build_info.cc.in"], + outs = ["internal/build_info.cc"], + cmd = """ +CC_COMPILER_VERSION=$$($(CC) --version | head -1); +V=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); +sed -e "s;@CMAKE_CXX_COMPILER_ID@;$(C_COMPILER);" \ + -e "s;@CMAKE_CXX_COMPILER_VERSION@;$${CC_COMPILER_VERSION};" \ + -e "s;@CMAKE_CXX_FLAGS@;$(CC_FLAGS);" \ + -e "s;\\$${CMAKE_CXX_FLAGS_.*};$(COMPILATION_MODE);" \ + -e "s;@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@;%s;" \ + -e "s;@GOOGLE_CLOUD_CPP_GIT_HEAD@;$${V};" < $< > $@ + """ % (GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE), + toolchains = [ + "@bazel_tools//tools/cpp:current_cc_toolchain", + "@bazel_tools//tools/cpp:cc_flags", + ], +) + load(":spanner_client.bzl", "spanner_client_hdrs", "spanner_client_srcs") cc_library( name = "spanner_client", - srcs = spanner_client_srcs, + srcs = spanner_client_srcs + ["internal/build_info.cc"], hdrs = spanner_client_hdrs, deps = [ "@com_github_googleapis_google_cloud_cpp//google/cloud:google_cloud_cpp_common", diff --git a/google/cloud/spanner/CMakeLists.txt b/google/cloud/spanner/CMakeLists.txt index a7a07c88..d282759e 100644 --- a/google/cloud/spanner/CMakeLists.txt +++ b/google/cloud/spanner/CMakeLists.txt @@ -25,6 +25,62 @@ set(DOXYGEN_PROJECT_NUMBER "${SPANNER_VERSION}") set(DOXYGEN_EXAMPLE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/samples) include(EnableDoxygen) +# Define a function to fetch the current git revision. Using a function creates +# a new scope, so the CMake variables do not leak to the global namespace. +function (google_cloud_cpp_spanner_initialize_git_head var) + set(result "") + # If we cannot find a `.git` directory do not even try to guess the git + # revision. + if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/.git) + set(result "unknown-commit") + # We need `git` to find the revision. + find_program(GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM NAMES git) + mark_as_advanced(GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM) + if (GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM) + # Run `git rev-parse --short HEAD` and capture the output in a + # variable. + execute_process(COMMAND "${GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM}" rev-parse + --short HEAD + OUTPUT_VARIABLE GIT_HEAD_LOG + ERROR_VARIABLE GIT_HEAD_LOG) + string(REPLACE "\n" + "" + result + "${GIT_HEAD_LOG}") + endif () + endif () + set(${var} "${result}" PARENT_SCOPE) +endfunction () + +# Capture the compiler version and the git revision into variables, then +# generate a config file with the values. +if (NOT "${GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA}" STREQUAL "") + # The build metadata flag is already defined, do not re-compute the + # initialization value. This works both when the user supplies + # -DGOOGLE_CLOUD_CPP_SPANNER_METADATA=value in the command line, and when + # GOOGLE_CLOUD_CPP_SPANNER_METADATA has a cached value + set(GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD "unused") +else() + google_cloud_cpp_spanner_initialize_git_head(GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD) +endif () + +# Define a CMake configuration option to set the build metadata. By default this +# is initialized from `git rev-parse --short HEAD`, but the developer (or the +# script building via CMake) can override the value. +set(GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA "${GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD}" + CACHE STRING "Append build metadata to the library version number") +# This option is rarely needed. Mark it as "advanced" to remove it from the +# default CMake UIs. +mark_as_advanced(GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA) + +message(STATUS "google-cloud-cpp-spanner build metadata set to" + " ${GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA}") + +# Create the file that captures build information. Having access to the compiler +# and build flags at runtime allows us to print better benchmark results. +string(TOUPPER "${CMAKE_BUILD_TYPE}" GOOGLE_CLOUD_CPP_SPANNER_BUILD_TYPE_UPPER) +configure_file(internal/build_info.cc.in internal/build_info.cc) + configure_file(version_info.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version_info.h) add_library(spanner_client backoff_policy.h @@ -38,6 +94,8 @@ add_library(spanner_client date.h internal/base64.cc internal/base64.h + internal/build_info.h + ${CMAKE_CURRENT_BINARY_DIR}/internal/build_info.cc internal/database_admin_retry.cc internal/database_admin_retry.h internal/database_admin_stub.cc @@ -102,6 +160,9 @@ add_library(googleapis-c++::spanner_client ALIAS spanner_client) include(CreateBazelConfig) create_bazel_config(spanner_client) +export_variables_to_bazel("spanner_client_version.bzl" + GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE) + # Define the tests in a function so we have a new scope for variable names. function (spanner_client_define_tests) # The tests require googletest to be installed. Force CMake to use the @@ -133,6 +194,7 @@ function (spanner_client_define_tests) database_admin_client_test.cc date_test.cc internal/base64_test.cc + internal/build_info_test.cc internal/date_test.cc internal/merge_chunk_test.cc internal/polling_loop_test.cc diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in new file mode 100644 index 00000000..9eccbe76 --- /dev/null +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -0,0 +1,94 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "google/cloud/spanner/internal/build_info.h" +#include "google/cloud/internal/port_platform.h" +#include +#include +#include + +namespace google { +namespace cloud { +namespace spanner { +inline namespace SPANNER_CLIENT_NS { +namespace internal { + +std::string CompilerVersion() { + return R"""(@CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPILER_VERSION@)"""; +} + +std::string CompilerFlags() { + static std::string const* const kFlags = [] { + auto* flags = new std::string(R"""(@CMAKE_CXX_FLAGS@)"""); + if (!flags->empty()) *flags += ' '; + *flags += + R"""(${CMAKE_CXX_FLAGS_${GOOGLE_CLOUD_CPP_SPANNER_BUILD_TYPE_UPPER}})"""; + return flags; + }(); + return *kFlags; +} + +std::string LanguageVersion() { + static std::string const* const kLanguageVersion = [] { + auto* v = new auto(CompilerVersion()); + for (char& c : *v) { + if (std::isspace(static_cast(c))) c = '-'; + } +#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + *v += "-ex"; +#else + *v += "-noex"; +#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + switch (__cplusplus) { + case 199711L: + *v += "-98"; + break; + case 201103L: + *v += "-2011"; + break; + case 201402L: + *v += "-2014"; + break; + case 201703L: + *v += "-2017"; + break; + default: + *v += "-unknown"; + } + return v; + }(); + return *kLanguageVersion; +} + +bool IsRelease() { + static bool const kIsRelease = []() -> bool { + std::string value = R"""(@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@)"""; + for (char& c : value) { + c = static_cast(std::tolower(static_cast(c))); + } + return value == "yes" || value == "1" || value == "true"; + }(); + + return kIsRelease; +} + +std::string BuildMetadata() { + return R"""(@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@)"""; +} + +} // namespace internal +} // namespace GOOGLE_CLOUD_CPP_NS +} // namespace spanner +} // namespace cloud +} // namespace google diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h new file mode 100644 index 00000000..650adb69 --- /dev/null +++ b/google/cloud/spanner/internal/build_info.h @@ -0,0 +1,47 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ +#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ + +#include "google/cloud/spanner/version.h" + +namespace google { +namespace cloud { +namespace spanner { +inline namespace SPANNER_CLIENT_NS { +namespace internal { + +/// The compiler version. +std::string CompilerVersion(); + +/// The compiler flags. +std::string CompilerFlags(); + +/// The language version for user-agent header. +std::string LanguageVersion(); + +/// True if this is a release, false for the development branches. +bool IsRelease(); + +/// Build metadata injected by the build system. +std::string BuildMetadata(); + +} // namespace internal +} // namespace SPANNER_CLIENT_NS +} // namespace spanner +} // namespace cloud +} // namespace google + +#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc new file mode 100644 index 00000000..8683d350 --- /dev/null +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -0,0 +1,63 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "google/cloud/spanner/internal/build_info.h" +#include + +namespace google { +namespace cloud { +namespace spanner { +inline namespace SPANNER_CLIENT_NS { +namespace internal { +namespace { + +using ::testing::HasSubstr; +using ::testing::MatchesRegex; + +TEST(BuildInfo, CompilerVersion) { + auto cv = CompilerVersion(); + EXPECT_FALSE(cv.empty()); +} + +TEST(BuildInfo, CompilerFlags) { + auto cf = CompilerFlags(); + EXPECT_FALSE(cf.empty()); +} + +TEST(BuildInfo, LanguageVersion) { + auto lv = LanguageVersion(); + EXPECT_THAT(lv, ::testing::AnyOf(HasSubstr("-noex-"), HasSubstr("-ex-"))); + EXPECT_THAT(lv, Not(HasSubstr(" "))); +#ifndef _WIN32 + // Brackets for regex don't work on windows. + EXPECT_THAT(lv, MatchesRegex(R"([0-9A-Za-z_.-]+)")); +#endif +} + +TEST(BuildInfo, IsRelease) { + bool const b = IsRelease(); + EXPECT_TRUE(b || !b); +} + +TEST(BuildInfo, BuildMetadata) { + auto const md = BuildMetadata(); + EXPECT_FALSE(md.empty()); +} + +} // namespace +} // namespace internal +} // namespace SPANNER_CLIENT_NS +} // namespace spanner +} // namespace cloud +} // namespace google diff --git a/google/cloud/spanner/spanner_client.bzl b/google/cloud/spanner/spanner_client.bzl index 1fd34e70..ba1ffc17 100644 --- a/google/cloud/spanner/spanner_client.bzl +++ b/google/cloud/spanner/spanner_client.bzl @@ -24,6 +24,7 @@ spanner_client_hdrs = [ "database_admin_client.h", "date.h", "internal/base64.h", + "internal/build_info.h", "internal/database_admin_retry.h", "internal/database_admin_stub.h", "internal/date.h", diff --git a/google/cloud/spanner/spanner_client_unit_tests.bzl b/google/cloud/spanner/spanner_client_unit_tests.bzl index 287b0c13..0f1dd994 100644 --- a/google/cloud/spanner/spanner_client_unit_tests.bzl +++ b/google/cloud/spanner/spanner_client_unit_tests.bzl @@ -22,6 +22,7 @@ spanner_client_unit_tests = [ "database_admin_client_test.cc", "date_test.cc", "internal/base64_test.cc", + "internal/build_info_test.cc", "internal/date_test.cc", "internal/merge_chunk_test.cc", "internal/polling_loop_test.cc", diff --git a/google/cloud/spanner/spanner_client_version.bzl b/google/cloud/spanner/spanner_client_version.bzl new file mode 100644 index 00000000..c540cb71 --- /dev/null +++ b/google/cloud/spanner/spanner_client_version.bzl @@ -0,0 +1,19 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed + +"""Automatically generated version numbers - DO NOT EDIT.""" + +GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE = "" From 31aa0563ba1cac2be748163eafa3baa179ca6674 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Wed, 31 Jul 2019 10:08:26 -0400 Subject: [PATCH 02/19] formatted --- google/cloud/spanner/CMakeLists.txt | 14 ++++++++------ google/cloud/spanner/internal/build_info.cc.in | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/google/cloud/spanner/CMakeLists.txt b/google/cloud/spanner/CMakeLists.txt index d282759e..59b1a31f 100644 --- a/google/cloud/spanner/CMakeLists.txt +++ b/google/cloud/spanner/CMakeLists.txt @@ -39,8 +39,8 @@ function (google_cloud_cpp_spanner_initialize_git_head var) if (GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM) # Run `git rev-parse --short HEAD` and capture the output in a # variable. - execute_process(COMMAND "${GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM}" rev-parse - --short HEAD + execute_process(COMMAND "${GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM}" + rev-parse --short HEAD OUTPUT_VARIABLE GIT_HEAD_LOG ERROR_VARIABLE GIT_HEAD_LOG) string(REPLACE "\n" @@ -60,14 +60,16 @@ if (NOT "${GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA}" STREQUAL "") # -DGOOGLE_CLOUD_CPP_SPANNER_METADATA=value in the command line, and when # GOOGLE_CLOUD_CPP_SPANNER_METADATA has a cached value set(GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD "unused") -else() - google_cloud_cpp_spanner_initialize_git_head(GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD) +else () + google_cloud_cpp_spanner_initialize_git_head( + GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD) endif () # Define a CMake configuration option to set the build metadata. By default this # is initialized from `git rev-parse --short HEAD`, but the developer (or the # script building via CMake) can override the value. -set(GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA "${GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD}" +set(GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA + "${GOOGLE_CLOUD_CPP_SPANNER_GIT_HEAD}" CACHE STRING "Append build metadata to the library version number") # This option is rarely needed. Mark it as "advanced" to remove it from the # default CMake UIs. @@ -83,6 +85,7 @@ configure_file(internal/build_info.cc.in internal/build_info.cc) configure_file(version_info.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version_info.h) add_library(spanner_client + ${CMAKE_CURRENT_BINARY_DIR}/internal/build_info.cc backoff_policy.h client.cc client.h @@ -95,7 +98,6 @@ add_library(spanner_client internal/base64.cc internal/base64.h internal/build_info.h - ${CMAKE_CURRENT_BINARY_DIR}/internal/build_info.cc internal/database_admin_retry.cc internal/database_admin_retry.h internal/database_admin_stub.cc diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index 9eccbe76..ff3b267d 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -43,7 +43,7 @@ std::string LanguageVersion() { static std::string const* const kLanguageVersion = [] { auto* v = new auto(CompilerVersion()); for (char& c : *v) { - if (std::isspace(static_cast(c))) c = '-'; + if (std::isspace(static_cast(c)) != 0) c = '-'; } #if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS *v += "-ex"; @@ -73,6 +73,7 @@ std::string LanguageVersion() { bool IsRelease() { static bool const kIsRelease = []() -> bool { + // NOLINTNEXTLINE(readability-redundant-string-init) std::string value = R"""(@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@)"""; for (char& c : value) { c = static_cast(std::tolower(static_cast(c))); From d33d4b45967c236c431202e9497808607c2b89de Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Wed, 31 Jul 2019 11:17:54 -0400 Subject: [PATCH 03/19] fixed regex --- google/cloud/spanner/internal/build_info_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index 8683d350..2b4ee2a9 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -40,8 +40,8 @@ TEST(BuildInfo, LanguageVersion) { EXPECT_THAT(lv, ::testing::AnyOf(HasSubstr("-noex-"), HasSubstr("-ex-"))); EXPECT_THAT(lv, Not(HasSubstr(" "))); #ifndef _WIN32 - // Brackets for regex don't work on windows. - EXPECT_THAT(lv, MatchesRegex(R"([0-9A-Za-z_.-]+)")); + // Brackets don't work with MatchesRegex() on Windows. + EXPECT_THAT(lv, MatchesRegex(R"([0-9A-Za-z/()_.-]+)")); #endif } From e0a155b585beb4b42a68a7867c3a73ee1a31b1fb Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Wed, 31 Jul 2019 13:29:42 -0400 Subject: [PATCH 04/19] fixed include guards --- google/cloud/spanner/internal/build_info.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index 650adb69..457efa84 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ -#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ +#ifndef GOOGLE_CLOUD_CPP_SPANNER_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ +#define GOOGLE_CLOUD_CPP_SPANNER_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ #include "google/cloud/spanner/version.h" @@ -44,4 +44,4 @@ std::string BuildMetadata(); } // namespace cloud } // namespace google -#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ +#endif // GOOGLE_CLOUD_CPP_SPANNER_GOOGLE_CLOUD_SPANNER_INTERNAL_BUILD_INFO_H_ From 669100d4a4e7406f0db873bbcb20b95aa88b9e3a Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Wed, 31 Jul 2019 16:55:21 -0400 Subject: [PATCH 05/19] changed formatting of most functions --- google/cloud/spanner/BUILD | 6 +- google/cloud/spanner/CMakeLists.txt | 3 +- .../cloud/spanner/internal/build_info.cc.in | 61 +++++++++++++------ google/cloud/spanner/internal/build_info.h | 45 ++++++++++++-- .../cloud/spanner/internal/build_info_test.cc | 26 +++++--- 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index b50e6b7d..9f78fed7 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -25,12 +25,12 @@ genrule( cmd = """ CC_COMPILER_VERSION=$$($(CC) --version | head -1); V=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); -sed -e "s;@CMAKE_CXX_COMPILER_ID@;$(C_COMPILER);" \ +sed -e "s;@CMAKE_CXX_COMPILER@;$$(basename $(CC));" \ -e "s;@CMAKE_CXX_COMPILER_VERSION@;$${CC_COMPILER_VERSION};" \ -e "s;@CMAKE_CXX_FLAGS@;$(CC_FLAGS);" \ - -e "s;\\$${CMAKE_CXX_FLAGS_.*};$(COMPILATION_MODE);" \ + -e "s;\\$${CMAKE_CXX_FLAGS_.*};-c $(COMPILATION_MODE);" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@;%s;" \ - -e "s;@GOOGLE_CLOUD_CPP_GIT_HEAD@;$${V};" < $< > $@ + -e "s;@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@;$${V};" < $< > $@ """ % (GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE), toolchains = [ "@bazel_tools//tools/cpp:current_cc_toolchain", diff --git a/google/cloud/spanner/CMakeLists.txt b/google/cloud/spanner/CMakeLists.txt index 59b1a31f..7d8e360a 100644 --- a/google/cloud/spanner/CMakeLists.txt +++ b/google/cloud/spanner/CMakeLists.txt @@ -28,11 +28,10 @@ include(EnableDoxygen) # Define a function to fetch the current git revision. Using a function creates # a new scope, so the CMake variables do not leak to the global namespace. function (google_cloud_cpp_spanner_initialize_git_head var) - set(result "") + set(result "unknown") # If we cannot find a `.git` directory do not even try to guess the git # revision. if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/.git) - set(result "unknown-commit") # We need `git` to find the revision. find_program(GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM NAMES git) mark_as_advanced(GOOGLE_CLOUD_CPP_SPANNER_GIT_PROGRAM) diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index ff3b267d..b606b1ca 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -24,12 +24,37 @@ namespace spanner { inline namespace SPANNER_CLIENT_NS { namespace internal { +std::string CompilerName() { + static auto const* const kName = [] { + auto* s = new std::string(R"""(@CMAKE_CXX_COMPILER@)"""); + auto pos = s->rfind('/'); + if (pos != std::string::npos) s->erase(0, pos + 1); + for (char& c : *s) { + if (c == '+') c = 'x'; + } + return s; + }(); + return *kName; +} + std::string CompilerVersion() { - return R"""(@CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPILER_VERSION@)"""; + static auto const* const kVersion = [] { + auto* s = new std::string(R"""(@CMAKE_CXX_COMPILER_VERSION@)"""); + auto illegal_punct = [](unsigned char c) -> bool { + if (c == '.' || c == '-') return false; // allowed + return std::ispunct(c) != 0; + }; + s->erase(std::remove_if(s->begin(), s->end(), illegal_punct), s->end()); + for (char& c : *s) { + if (std::isspace(static_cast(c)) != 0) c = '-'; + } + return s; + }(); + return *kVersion; } std::string CompilerFlags() { - static std::string const* const kFlags = [] { + static auto const* const kFlags = [] { auto* flags = new std::string(R"""(@CMAKE_CXX_FLAGS@)"""); if (!flags->empty()) *flags += ' '; *flags += @@ -40,33 +65,30 @@ std::string CompilerFlags() { } std::string LanguageVersion() { - static std::string const* const kLanguageVersion = [] { - auto* v = new auto(CompilerVersion()); - for (char& c : *v) { - if (std::isspace(static_cast(c)) != 0) c = '-'; - } -#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS - *v += "-ex"; -#else - *v += "-noex"; -#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + static auto const* const kLanguageVersion = [] { + auto* s = new std::string; switch (__cplusplus) { case 199711L: - *v += "-98"; + *s += "98"; break; case 201103L: - *v += "-2011"; + *s += "2011"; break; case 201402L: - *v += "-2014"; + *s += "2014"; break; case 201703L: - *v += "-2017"; + *s += "2017"; break; default: - *v += "-unknown"; + *s += "unknown"; } - return v; +#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + *s += "-ex"; +#else + *s += "-noex"; +#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + return s; }(); return *kLanguageVersion; } @@ -80,12 +102,11 @@ bool IsRelease() { } return value == "yes" || value == "1" || value == "true"; }(); - return kIsRelease; } std::string BuildMetadata() { - return R"""(@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@)"""; + return R"""(sha.@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@)"""; } } // namespace internal diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index 457efa84..0026431d 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -23,19 +23,54 @@ namespace spanner { inline namespace SPANNER_CLIENT_NS { namespace internal { -/// The compiler version. +/** + * Returns the compiler. + * + * This is usually the basename of the compile command that was used. For + * example, "clang" or "gcc". In the case of "g++" or "clang++", they will be + * rewritten to "gxx" and "clangxx" since '+' is an illegal character for the + * server-side fields that look at these values. + */ +std::string CompilerName(); + +/** + * Returns the compiler version. + * + * This string may be something simple like "9.1.1" or it may be something more + * verbose like "clang-version-8.0.0-Fedora-8.0.0-1.fc30". + */ std::string CompilerVersion(); -/// The compiler flags. +/** + * Returns the compiler flags. + * + * Examples include "-c fastbuild" or "-O2 -DNDEBUG". + */ std::string CompilerFlags(); -/// The language version for user-agent header. +/** + * Returns the 4-digit year of the C++ language standard along with an + * exception indicator. + * + * The returned string is suffixed with "-ex" or "-noex" to indicate whether or + * not the code was compiled with exceptions enabled. + * + * Example return values: "2011-ex", "2017-noex" "unknown-ex" + */ std::string LanguageVersion(); -/// True if this is a release, false for the development branches. +/** + * Returns true if this is a release branch. + */ bool IsRelease(); -/// Build metadata injected by the build system. +/** + * Returns the metadata injected by the build system. + * + * The returned info is the string "sha." followed by a short commit hash. See + * https://semver.org/#spec-item-10 for more details about the use and format + * of build metadata. + */ std::string BuildMetadata(); } // namespace internal diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index 2b4ee2a9..5ec12e7e 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -22,37 +22,49 @@ inline namespace SPANNER_CLIENT_NS { namespace internal { namespace { -using ::testing::HasSubstr; -using ::testing::MatchesRegex; +TEST(BuildInfo, CompilerName) { + auto cn = CompilerName(); + EXPECT_FALSE(cn.empty()); + EXPECT_THAT(cn, ::testing::Not(::testing::HasSubstr("@"))); +} TEST(BuildInfo, CompilerVersion) { auto cv = CompilerVersion(); EXPECT_FALSE(cv.empty()); + EXPECT_THAT(cv, ::testing::Not(::testing::HasSubstr("@"))); +#ifndef _WIN32 // gMock's regex brackets don't work on Windows. + // Look for something that looks vaguely like an X.Y version number. + EXPECT_THAT(cv, ::testing::ContainsRegex(R"([0-9].[0-9])")); +#endif } TEST(BuildInfo, CompilerFlags) { auto cf = CompilerFlags(); EXPECT_FALSE(cf.empty()); + EXPECT_THAT(cf, ::testing::Not(::testing::HasSubstr("@"))); } TEST(BuildInfo, LanguageVersion) { + using ::testing::HasSubstr; auto lv = LanguageVersion(); - EXPECT_THAT(lv, ::testing::AnyOf(HasSubstr("-noex-"), HasSubstr("-ex-"))); + EXPECT_THAT(lv, ::testing::AnyOf(HasSubstr("-noex"), HasSubstr("-ex"))); EXPECT_THAT(lv, Not(HasSubstr(" "))); -#ifndef _WIN32 - // Brackets don't work with MatchesRegex() on Windows. - EXPECT_THAT(lv, MatchesRegex(R"([0-9A-Za-z/()_.-]+)")); + EXPECT_THAT(lv, ::testing::Not(::testing::HasSubstr("@"))); +#ifndef _WIN32 // gMock's regex brackets don't work on Windows. + EXPECT_THAT(lv, ::testing::MatchesRegex(R"([0-9A-Za-z/()_.-]+)")); #endif } TEST(BuildInfo, IsRelease) { bool const b = IsRelease(); + // We want to test this, but either value is fine. EXPECT_TRUE(b || !b); } TEST(BuildInfo, BuildMetadata) { auto const md = BuildMetadata(); - EXPECT_FALSE(md.empty()); + EXPECT_THAT(md, ::testing::MatchesRegex(R"(sha\..+)")); + EXPECT_THAT(md, ::testing::Not(::testing::HasSubstr("@"))); } } // namespace From 2ed2a450c28ccda18ef5e62ed630d8c4d1dc611d Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 08:59:07 -0400 Subject: [PATCH 06/19] reverted regex changes --- google/cloud/spanner/internal/build_info_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index 5ec12e7e..afed5e37 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -51,7 +51,7 @@ TEST(BuildInfo, LanguageVersion) { EXPECT_THAT(lv, Not(HasSubstr(" "))); EXPECT_THAT(lv, ::testing::Not(::testing::HasSubstr("@"))); #ifndef _WIN32 // gMock's regex brackets don't work on Windows. - EXPECT_THAT(lv, ::testing::MatchesRegex(R"([0-9A-Za-z/()_.-]+)")); + EXPECT_THAT(lv, ::testing::MatchesRegex(R"([0-9A-Za-z_.-]+)")); #endif } From efb2886e433635f635fcfc62e92947302480638d Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 09:46:10 -0400 Subject: [PATCH 07/19] better deduping of punct --- google/cloud/spanner/internal/build_info.cc.in | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index b606b1ca..caaf5d6b 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -40,14 +40,15 @@ std::string CompilerName() { std::string CompilerVersion() { static auto const* const kVersion = [] { auto* s = new std::string(R"""(@CMAKE_CXX_COMPILER_VERSION@)"""); - auto illegal_punct = [](unsigned char c) -> bool { - if (c == '.' || c == '-') return false; // allowed - return std::ispunct(c) != 0; - }; - s->erase(std::remove_if(s->begin(), s->end(), illegal_punct), s->end()); + if (s->empty()) *s = "unknown"; // should never be empty. for (char& c : *s) { - if (std::isspace(static_cast(c)) != 0) c = '-'; + if (c != '.' && c != '-' && !std::isalnum(static_cast(c))) + c = '-'; } + std::unique(s->begin(), s->end(), [](char a, char b) -> bool { + return std::ispunct(a) && std::ispunct(b); + }); + if (s->back() == '-') s->pop_back(); return s; }(); return *kVersion; From 364db20ade5888f9c6cb2537a5eeb113a364f1d1 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 11:12:13 -0400 Subject: [PATCH 08/19] added scripts to make bazel build look like cmake build --- bazel/BUILD | 5 +++ bazel/compiler_id.sh | 32 ++++++++++++++ bazel/compiler_version.sh | 12 ++++++ google/cloud/spanner/BUILD | 11 +++-- .../cloud/spanner/internal/build_info.cc.in | 43 +++++-------------- google/cloud/spanner/internal/build_info.h | 25 ++++++----- .../cloud/spanner/internal/build_info_test.cc | 29 ++++++++++++- 7 files changed, 106 insertions(+), 51 deletions(-) create mode 100755 bazel/compiler_id.sh create mode 100755 bazel/compiler_version.sh diff --git a/bazel/BUILD b/bazel/BUILD index 9da2a22a..56e54ba6 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -15,3 +15,8 @@ licenses(["notice"]) # Apache v2 package(default_visibility = ["//:__subpackages__"]) + +exports_files([ + "compiler_id.sh", + "compiler_version.sh", +]) diff --git a/bazel/compiler_id.sh b/bazel/compiler_id.sh new file mode 100755 index 00000000..20c30255 --- /dev/null +++ b/bazel/compiler_id.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# +# Given an argument that is the path to a compiler, tries to determine an +# identification string for the compiler according to the CMake-defined IDs: +# https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html + +if [[ ! -e "${1}" ]]; then + echo "Usage: $0 " + exit 1 +fi + +version="$(${1} --version 2> /dev/null \ + | head -1 \ + | tr '[:upper:]' '[:lower:]')" + +case "${version}" in + *gcc* | *g++*) + echo "GNU" + ;; + + *clang*) + echo "Clang" + ;; + + *msvc* | *microsoft*) + echo "Clang" + ;; + + *) + echo "unknown" + ;; +esac diff --git a/bazel/compiler_version.sh b/bazel/compiler_version.sh new file mode 100755 index 00000000..f0876000 --- /dev/null +++ b/bazel/compiler_version.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# +# Given an argument that is the path to a compiler, tries to determine +# the compiler's version by looking for the first string that looks like +# X.Y with more optional numbers '.', '-', and '+'. + +if [[ ! -e "${1}" ]]; then + echo "Usage: $0 " + exit 1 +fi + +${1} --version 2> /dev/null | grep -Eo "[0-9]+\.[0-9.+-]+" | head -1 diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index 9f78fed7..9bb95c41 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -23,10 +23,11 @@ genrule( srcs = ["internal/build_info.cc.in"], outs = ["internal/build_info.cc"], cmd = """ -CC_COMPILER_VERSION=$$($(CC) --version | head -1); V=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); -sed -e "s;@CMAKE_CXX_COMPILER@;$$(basename $(CC));" \ - -e "s;@CMAKE_CXX_COMPILER_VERSION@;$${CC_COMPILER_VERSION};" \ +CC_VERSION=$$(bazel/compiler_version.sh $(CC)); +CC_ID=$$(bazel/compiler_id.sh $(CC)); +sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ + -e "s;@CMAKE_CXX_COMPILER_VERSION@;$${CC_VERSION};" \ -e "s;@CMAKE_CXX_FLAGS@;$(CC_FLAGS);" \ -e "s;\\$${CMAKE_CXX_FLAGS_.*};-c $(COMPILATION_MODE);" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@;%s;" \ @@ -36,6 +37,10 @@ sed -e "s;@CMAKE_CXX_COMPILER@;$$(basename $(CC));" \ "@bazel_tools//tools/cpp:current_cc_toolchain", "@bazel_tools//tools/cpp:cc_flags", ], + tools = [ + "//bazel:compiler_id.sh", + "//bazel:compiler_version.sh", + ] ) load(":spanner_client.bzl", "spanner_client_hdrs", "spanner_client_srcs") diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index caaf5d6b..90aa8bc8 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -24,35 +24,9 @@ namespace spanner { inline namespace SPANNER_CLIENT_NS { namespace internal { -std::string CompilerName() { - static auto const* const kName = [] { - auto* s = new std::string(R"""(@CMAKE_CXX_COMPILER@)"""); - auto pos = s->rfind('/'); - if (pos != std::string::npos) s->erase(0, pos + 1); - for (char& c : *s) { - if (c == '+') c = 'x'; - } - return s; - }(); - return *kName; -} +std::string CompilerName() { return R"""(@CMAKE_CXX_COMPILER_ID@)"""; } -std::string CompilerVersion() { - static auto const* const kVersion = [] { - auto* s = new std::string(R"""(@CMAKE_CXX_COMPILER_VERSION@)"""); - if (s->empty()) *s = "unknown"; // should never be empty. - for (char& c : *s) { - if (c != '.' && c != '-' && !std::isalnum(static_cast(c))) - c = '-'; - } - std::unique(s->begin(), s->end(), [](char a, char b) -> bool { - return std::ispunct(a) && std::ispunct(b); - }); - if (s->back() == '-') s->pop_back(); - return s; - }(); - return *kVersion; -} +std::string CompilerVersion() { return R"""(@CMAKE_CXX_COMPILER_VERSION@)"""; } std::string CompilerFlags() { static auto const* const kFlags = [] { @@ -65,6 +39,14 @@ std::string CompilerFlags() { return *kFlags; } +std::string CompilerFeatures() { +#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS + return "ex"; +#else + return "noex"; +#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS +} + std::string LanguageVersion() { static auto const* const kLanguageVersion = [] { auto* s = new std::string; @@ -84,11 +66,6 @@ std::string LanguageVersion() { default: *s += "unknown"; } -#if GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS - *s += "-ex"; -#else - *s += "-noex"; -#endif // GOOGLE_CLOUD_CPP_HAVE_EXCEPTIONS return s; }(); return *kLanguageVersion; diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index 0026431d..a63f2e1f 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -24,20 +24,17 @@ inline namespace SPANNER_CLIENT_NS { namespace internal { /** - * Returns the compiler. + * Returns the compiler ID. * - * This is usually the basename of the compile command that was used. For - * example, "clang" or "gcc". In the case of "g++" or "clang++", they will be - * rewritten to "gxx" and "clangxx" since '+' is an illegal character for the - * server-side fields that look at these values. + * The Compiler ID is a string like "GNU" or "Clang", as described by + * https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html */ std::string CompilerName(); /** * Returns the compiler version. * - * This string may be something simple like "9.1.1" or it may be something more - * verbose like "clang-version-8.0.0-Fedora-8.0.0-1.fc30". + * This string will be something like "9.1.1". */ std::string CompilerVersion(); @@ -49,13 +46,15 @@ std::string CompilerVersion(); std::string CompilerFlags(); /** - * Returns the 4-digit year of the C++ language standard along with an - * exception indicator. + * Returns certain interesting compiler features. * - * The returned string is suffixed with "-ex" or "-noex" to indicate whether or - * not the code was compiled with exceptions enabled. - * - * Example return values: "2011-ex", "2017-noex" "unknown-ex" + * Currently this returns one of "ex" or "noex" to indicate whether or not + * C++ exceptions are enabled. + */ +std::string CompilerFeatures(); + +/** + * Returns the 4-digit year of the C++ language standard. */ std::string LanguageVersion(); diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index afed5e37..e5878568 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -44,11 +44,16 @@ TEST(BuildInfo, CompilerFlags) { EXPECT_THAT(cf, ::testing::Not(::testing::HasSubstr("@"))); } +TEST(BuildInfo, CompilerFeatures) { + using ::testing::Eq; + auto cf = CompilerFeatures(); + EXPECT_THAT(cf, ::testing::AnyOf(Eq("noex"), Eq("ex"))); +} + TEST(BuildInfo, LanguageVersion) { using ::testing::HasSubstr; auto lv = LanguageVersion(); - EXPECT_THAT(lv, ::testing::AnyOf(HasSubstr("-noex"), HasSubstr("-ex"))); - EXPECT_THAT(lv, Not(HasSubstr(" "))); + EXPECT_FALSE(lv.empty()); EXPECT_THAT(lv, ::testing::Not(::testing::HasSubstr("@"))); #ifndef _WIN32 // gMock's regex brackets don't work on Windows. EXPECT_THAT(lv, ::testing::MatchesRegex(R"([0-9A-Za-z_.-]+)")); @@ -67,6 +72,26 @@ TEST(BuildInfo, BuildMetadata) { EXPECT_THAT(md, ::testing::Not(::testing::HasSubstr("@"))); } +TEST(BuildInfo, ApiClientHeader) { + // The build info is used to generate the "API Client Header", which is a + // gRPC metadata attribute with the name 'x-goog-api-client'. This test + // generates that whole string as a sanity check that it will contain the + // desired format. + + std::string const api_client_header = "gl-cpp/" + // + CompilerName() + '-' + // + CompilerVersion() + '-' + // + CompilerFeatures() + '-' + // + LanguageVersion(); + EXPECT_THAT(api_client_header, ::testing::Not(::testing::HasSubstr("@"))); + +#ifndef _WIN32 // gMock's regex brackets don't work on Windows. + EXPECT_THAT(api_client_header, + ::testing::MatchesRegex( + R"(gl-cpp/(Clang|GNU)-[0-9.+-]+-(no)?ex-20[1-9][0-9])")); +#endif +} + } // namespace } // namespace internal } // namespace SPANNER_CLIENT_NS From 8f298feac64066272c48be6f71dc6ec714844840 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 11:17:09 -0400 Subject: [PATCH 09/19] formatted --- google/cloud/spanner/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index 9bb95c41..7e03d1b4 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -40,7 +40,7 @@ sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ tools = [ "//bazel:compiler_id.sh", "//bazel:compiler_version.sh", - ] + ], ) load(":spanner_client.bzl", "spanner_client_hdrs", "spanner_client_srcs") From b648b606e0feac085b33a0915b013bcab92a6019 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 13:16:11 -0400 Subject: [PATCH 10/19] wording --- bazel/compiler_id.sh | 2 +- bazel/compiler_version.sh | 4 ++-- google/cloud/spanner/internal/build_info.cc.in | 2 +- google/cloud/spanner/internal/build_info.h | 2 +- google/cloud/spanner/internal/build_info_test.cc | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bazel/compiler_id.sh b/bazel/compiler_id.sh index 20c30255..fa56a658 100755 --- a/bazel/compiler_id.sh +++ b/bazel/compiler_id.sh @@ -9,7 +9,7 @@ if [[ ! -e "${1}" ]]; then exit 1 fi -version="$(${1} --version 2> /dev/null \ +version="$("${1}" --version 2> /dev/null \ | head -1 \ | tr '[:upper:]' '[:lower:]')" diff --git a/bazel/compiler_version.sh b/bazel/compiler_version.sh index f0876000..686f7b4d 100755 --- a/bazel/compiler_version.sh +++ b/bazel/compiler_version.sh @@ -2,11 +2,11 @@ # # Given an argument that is the path to a compiler, tries to determine # the compiler's version by looking for the first string that looks like -# X.Y with more optional numbers '.', '-', and '+'. +# X.Y with more optional numbers, '.', '-', and '+'. if [[ ! -e "${1}" ]]; then echo "Usage: $0 " exit 1 fi -${1} --version 2> /dev/null | grep -Eo "[0-9]+\.[0-9.+-]+" | head -1 +"${1}" --version 2> /dev/null | grep -Eo "[0-9]+\.[0-9.+-]+" | head -1 diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index 90aa8bc8..1780cf66 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -24,7 +24,7 @@ namespace spanner { inline namespace SPANNER_CLIENT_NS { namespace internal { -std::string CompilerName() { return R"""(@CMAKE_CXX_COMPILER_ID@)"""; } +std::string CompilerId() { return R"""(@CMAKE_CXX_COMPILER_ID@)"""; } std::string CompilerVersion() { return R"""(@CMAKE_CXX_COMPILER_VERSION@)"""; } diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index a63f2e1f..6c0ec1a8 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -29,7 +29,7 @@ namespace internal { * The Compiler ID is a string like "GNU" or "Clang", as described by * https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html */ -std::string CompilerName(); +std::string CompilerId(); /** * Returns the compiler version. diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index e5878568..f5294550 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -22,8 +22,8 @@ inline namespace SPANNER_CLIENT_NS { namespace internal { namespace { -TEST(BuildInfo, CompilerName) { - auto cn = CompilerName(); +TEST(BuildInfo, CompilerId) { + auto cn = CompilerId(); EXPECT_FALSE(cn.empty()); EXPECT_THAT(cn, ::testing::Not(::testing::HasSubstr("@"))); } @@ -40,13 +40,13 @@ TEST(BuildInfo, CompilerVersion) { TEST(BuildInfo, CompilerFlags) { auto cf = CompilerFlags(); - EXPECT_FALSE(cf.empty()); EXPECT_THAT(cf, ::testing::Not(::testing::HasSubstr("@"))); } TEST(BuildInfo, CompilerFeatures) { using ::testing::Eq; auto cf = CompilerFeatures(); + EXPECT_FALSE(cf.empty()); EXPECT_THAT(cf, ::testing::AnyOf(Eq("noex"), Eq("ex"))); } @@ -79,7 +79,7 @@ TEST(BuildInfo, ApiClientHeader) { // desired format. std::string const api_client_header = "gl-cpp/" + // - CompilerName() + '-' + // + CompilerId() + '-' + // CompilerVersion() + '-' + // CompilerFeatures() + '-' + // LanguageVersion(); From 10260e56871f50da51b15d08db0b3c8a1278d8de Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 13:46:13 -0400 Subject: [PATCH 11/19] use bazel's location function to find scripts --- google/cloud/spanner/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index 7e03d1b4..fc7e1d89 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -24,8 +24,8 @@ genrule( outs = ["internal/build_info.cc"], cmd = """ V=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); -CC_VERSION=$$(bazel/compiler_version.sh $(CC)); -CC_ID=$$(bazel/compiler_id.sh $(CC)); +CC_VERSION=$$($(location //bazel:compiler_version.sh) $(CC)); +CC_ID=$$($(location //bazel:compiler_id.sh) $(CC)); sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ -e "s;@CMAKE_CXX_COMPILER_VERSION@;$${CC_VERSION};" \ -e "s;@CMAKE_CXX_FLAGS@;$(CC_FLAGS);" \ From 1fbc12a095e543bc06faf5a7701fbfb8e275bb1f Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Thu, 1 Aug 2019 21:48:13 -0400 Subject: [PATCH 12/19] PR comments: fixed some //build and //ci scripts --- bazel/compiler_id.sh | 18 +++++++++++++++++- bazel/compiler_version.sh | 14 ++++++++++++++ ci/kokoro/docker/build.sh | 5 ----- ci/kokoro/docker/upload-coverage.sh | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/bazel/compiler_id.sh b/bazel/compiler_id.sh index fa56a658..a41d073a 100755 --- a/bazel/compiler_id.sh +++ b/bazel/compiler_id.sh @@ -1,5 +1,19 @@ #!/bin/bash # +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# # Given an argument that is the path to a compiler, tries to determine an # identification string for the compiler according to the CMake-defined IDs: # https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html @@ -23,7 +37,9 @@ case "${version}" in ;; *msvc* | *microsoft*) - echo "Clang" + # I don't think "--version" above will actually work on Windows, so we + # should figure out how to do that correctly. See #281. + echo "MSVC" ;; *) diff --git a/bazel/compiler_version.sh b/bazel/compiler_version.sh index 686f7b4d..20b13484 100755 --- a/bazel/compiler_version.sh +++ b/bazel/compiler_version.sh @@ -1,5 +1,19 @@ #!/bin/bash # +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# # Given an argument that is the path to a compiler, tries to determine # the compiler's version by looking for the first string that looks like # X.Y with more optional numbers, '.', '-', and '+'. diff --git a/ci/kokoro/docker/build.sh b/ci/kokoro/docker/build.sh index 39a091c6..71be69a6 100755 --- a/ci/kokoro/docker/build.sh +++ b/ci/kokoro/docker/build.sh @@ -120,7 +120,6 @@ elif [[ "${BUILD_NAME}" = "cxx17" ]]; then in_docker_script="ci/kokoro/docker/build-in-docker-cmake.sh" elif [[ "${BUILD_NAME}" = "coverage" ]]; then export BUILD_TYPE=Coverage - export CODE_COVERAGE=yes export RUN_INTEGRATION_TESTS=yes export DISTRO=fedora-install export DISTRO_VERSION=30 @@ -229,10 +228,6 @@ docker_flags=( # installations. "--env" "TEST_INSTALL=${TEST_INSTALL:-}" - # If set to 'yes', run compile with code coverage flags. Currently only the - # CMake builds use this flag. - "--env" "CODE_COVERAGE=${CODE_COVERAGE:-}" - # If set, pass -DGOOGLE_CLOUD_CPP_CXX_STANDARD= to CMake. "--env" "GOOGLE_CLOUD_CPP_CXX_STANDARD=${GOOGLE_CLOUD_CPP_CXX_STANDARD:-}" diff --git a/ci/kokoro/docker/upload-coverage.sh b/ci/kokoro/docker/upload-coverage.sh index 82d05af1..542a28bf 100755 --- a/ci/kokoro/docker/upload-coverage.sh +++ b/ci/kokoro/docker/upload-coverage.sh @@ -21,7 +21,7 @@ fi source "${PROJECT_ROOT}/ci/kokoro/define-docker-variables.sh" source "${PROJECT_ROOT}/ci/define-dump-log.sh" -if [[ "${CODE_COVERAGE:-}" != "yes" ]]; then +if [[ "${BUILD_NAME:-}" != "coverage" ]]; then # Not a code coverage build, exit silently. exit 0 fi From 2bf41cb88114d046dbb60a115496780e40f5810b Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 07:58:19 -0400 Subject: [PATCH 13/19] changed usage-check in scripts --- bazel/compiler_id.sh | 2 +- bazel/compiler_version.sh | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/bazel/compiler_id.sh b/bazel/compiler_id.sh index a41d073a..5e6b8f0e 100755 --- a/bazel/compiler_id.sh +++ b/bazel/compiler_id.sh @@ -18,7 +18,7 @@ # identification string for the compiler according to the CMake-defined IDs: # https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html -if [[ ! -e "${1}" ]]; then +if [[ $# -ne 1 ]]; then echo "Usage: $0 " exit 1 fi diff --git a/bazel/compiler_version.sh b/bazel/compiler_version.sh index 20b13484..846ea05b 100755 --- a/bazel/compiler_version.sh +++ b/bazel/compiler_version.sh @@ -18,9 +18,17 @@ # the compiler's version by looking for the first string that looks like # X.Y with more optional numbers, '.', '-', and '+'. -if [[ ! -e "${1}" ]]; then +if [[ $# -ne 1 ]]; then echo "Usage: $0 " exit 1 fi -"${1}" --version 2> /dev/null | grep -Eo "[0-9]+\.[0-9.+-]+" | head -1 +version="$("${1}" --version 2> /dev/null \ + | grep -Eo "[0-9]+\.[0-9.+-]+" \ + | head -1)" + +if [[ -n "${version}" ]]; then + echo "${version}" +else + echo unknown +fi From b98657794c6f679dd214b3edccdb07ffc48d0175 Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 09:20:45 -0400 Subject: [PATCH 14/19] fixed bazel's git commit stamping --- .bazelrc | 2 ++ bazel/workspace_status.sh | 24 ++++++++++++++++++++++++ google/cloud/spanner/BUILD | 6 +++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100755 bazel/workspace_status.sh diff --git a/.bazelrc b/.bazelrc index 8a1133e9..faab31ef 100644 --- a/.bazelrc +++ b/.bazelrc @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +build --workspace_status_command=bazel/workspace_status.sh + # Clang Sanitizers, use with (for example): # # --client_env=CXX=clang++ --client_env=CC=clang --config asan diff --git a/bazel/workspace_status.sh b/bazel/workspace_status.sh new file mode 100755 index 00000000..a1c029f2 --- /dev/null +++ b/bazel/workspace_status.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This script is meant to be run as bazel's `--workspace_status_command=` +# command. It should output space-separated "KEY value" pairs that bazel will +# store in the file bazel-out/stable-status.txt, which can be accessed from +# genrules(). For more info, see: +# https://docs.bazel.build/versions/master/user-manual.html#flag--workspace_status_command + +readonly commit="$(git rev-parse --short HEAD 2> /dev/null || echo unknown)" +echo "STABLE_GIT_COMMIT ${commit}" diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index fc7e1d89..f4fa2b61 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -22,8 +22,9 @@ genrule( name = "generate_build_info", srcs = ["internal/build_info.cc.in"], outs = ["internal/build_info.cc"], + stamp = 1, cmd = """ -V=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); +V=$$(grep STABLE_GIT_COMMIT bazel-out/stable-status.txt | cut -f2 -d' '); CC_VERSION=$$($(location //bazel:compiler_version.sh) $(CC)); CC_ID=$$($(location //bazel:compiler_id.sh) $(CC)); sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ @@ -55,6 +56,9 @@ cc_library( "@com_google_googleapis//:bigtable_protos", "@com_google_googleapis//:spanner_protos", ], + data = [ + ":generate_build_info", + ], ) load(":spanner_client_testing.bzl", "spanner_client_testing_hdrs", "spanner_client_testing_srcs") From b68b38bab2d90f9c01c60c404505f04c7d76f91b Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 09:34:11 -0400 Subject: [PATCH 15/19] relax compiler ID regex to work with AppleClang and others --- google/cloud/spanner/internal/build_info_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index f5294550..9df6e293 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -88,7 +88,7 @@ TEST(BuildInfo, ApiClientHeader) { #ifndef _WIN32 // gMock's regex brackets don't work on Windows. EXPECT_THAT(api_client_header, ::testing::MatchesRegex( - R"(gl-cpp/(Clang|GNU)-[0-9.+-]+-(no)?ex-20[1-9][0-9])")); + R"(gl-cpp/[A-Za-z0-9]+-[0-9.+-]+-(no)?ex-20[1-9][0-9])")); #endif } From a01f00e2e5a51674f83b9f0e890122ae5fffb96f Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 09:41:58 -0400 Subject: [PATCH 16/19] formatted --- google/cloud/spanner/BUILD | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index f4fa2b61..33513131 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -22,7 +22,6 @@ genrule( name = "generate_build_info", srcs = ["internal/build_info.cc.in"], outs = ["internal/build_info.cc"], - stamp = 1, cmd = """ V=$$(grep STABLE_GIT_COMMIT bazel-out/stable-status.txt | cut -f2 -d' '); CC_VERSION=$$($(location //bazel:compiler_version.sh) $(CC)); @@ -34,6 +33,7 @@ sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@;%s;" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@;$${V};" < $< > $@ """ % (GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE), + stamp = 1, toolchains = [ "@bazel_tools//tools/cpp:current_cc_toolchain", "@bazel_tools//tools/cpp:cc_flags", @@ -50,15 +50,15 @@ cc_library( name = "spanner_client", srcs = spanner_client_srcs + ["internal/build_info.cc"], hdrs = spanner_client_hdrs, + data = [ + ":generate_build_info", + ], deps = [ "@com_github_googleapis_google_cloud_cpp//google/cloud:google_cloud_cpp_common", "@com_github_googleapis_google_cloud_cpp//google/cloud/grpc_utils:google_cloud_cpp_grpc_utils", "@com_google_googleapis//:bigtable_protos", "@com_google_googleapis//:spanner_protos", ], - data = [ - ":generate_build_info", - ], ) load(":spanner_client_testing.bzl", "spanner_client_testing_hdrs", "spanner_client_testing_srcs") From 8994355d546dc49bbd0ef9d01135a597ef9155bd Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 12:15:24 -0400 Subject: [PATCH 17/19] renamed CompilerFlags -> BuildFlags --- google/cloud/spanner/internal/build_info.cc.in | 2 +- google/cloud/spanner/internal/build_info.h | 4 ++-- google/cloud/spanner/internal/build_info_test.cc | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index 1780cf66..90f5db1b 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -28,7 +28,7 @@ std::string CompilerId() { return R"""(@CMAKE_CXX_COMPILER_ID@)"""; } std::string CompilerVersion() { return R"""(@CMAKE_CXX_COMPILER_VERSION@)"""; } -std::string CompilerFlags() { +std::string BuildFlags() { static auto const* const kFlags = [] { auto* flags = new std::string(R"""(@CMAKE_CXX_FLAGS@)"""); if (!flags->empty()) *flags += ' '; diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index 6c0ec1a8..750bb721 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -39,11 +39,11 @@ std::string CompilerId(); std::string CompilerVersion(); /** - * Returns the compiler flags. + * Returns the build flags. * * Examples include "-c fastbuild" or "-O2 -DNDEBUG". */ -std::string CompilerFlags(); +std::string BuildFlags(); /** * Returns certain interesting compiler features. diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index 9df6e293..84690b2a 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -38,9 +38,9 @@ TEST(BuildInfo, CompilerVersion) { #endif } -TEST(BuildInfo, CompilerFlags) { - auto cf = CompilerFlags(); - EXPECT_THAT(cf, ::testing::Not(::testing::HasSubstr("@"))); +TEST(BuildInfo, BuildFlags) { + auto bf = BuildFlags(); + EXPECT_THAT(bf, ::testing::Not(::testing::HasSubstr("@"))); } TEST(BuildInfo, CompilerFeatures) { From 8ac854d8ed487b9c5ba0e9b998e4b6246944c19c Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 12:17:32 -0400 Subject: [PATCH 18/19] removes 'sha.' prefix from build metadata --- google/cloud/spanner/internal/build_info.cc.in | 2 +- google/cloud/spanner/internal/build_info.h | 6 +++--- google/cloud/spanner/internal/build_info_test.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/google/cloud/spanner/internal/build_info.cc.in b/google/cloud/spanner/internal/build_info.cc.in index 90f5db1b..f1b4a533 100644 --- a/google/cloud/spanner/internal/build_info.cc.in +++ b/google/cloud/spanner/internal/build_info.cc.in @@ -84,7 +84,7 @@ bool IsRelease() { } std::string BuildMetadata() { - return R"""(sha.@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@)"""; + return R"""(@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@)"""; } } // namespace internal diff --git a/google/cloud/spanner/internal/build_info.h b/google/cloud/spanner/internal/build_info.h index 750bb721..c450bd63 100644 --- a/google/cloud/spanner/internal/build_info.h +++ b/google/cloud/spanner/internal/build_info.h @@ -66,9 +66,9 @@ bool IsRelease(); /** * Returns the metadata injected by the build system. * - * The returned info is the string "sha." followed by a short commit hash. See - * https://semver.org/#spec-item-10 for more details about the use and format - * of build metadata. + * See https://semver.org/#spec-item-10 for more details about the use and + * format of build metadata. Typically, the the value returned here is a hash + * indicating a git commit. */ std::string BuildMetadata(); diff --git a/google/cloud/spanner/internal/build_info_test.cc b/google/cloud/spanner/internal/build_info_test.cc index 84690b2a..bff0784d 100644 --- a/google/cloud/spanner/internal/build_info_test.cc +++ b/google/cloud/spanner/internal/build_info_test.cc @@ -68,7 +68,7 @@ TEST(BuildInfo, IsRelease) { TEST(BuildInfo, BuildMetadata) { auto const md = BuildMetadata(); - EXPECT_THAT(md, ::testing::MatchesRegex(R"(sha\..+)")); + EXPECT_FALSE(md.empty()); EXPECT_THAT(md, ::testing::Not(::testing::HasSubstr("@"))); } From 12b9a536f3c211d81dff43cdeea62fcc35277cdd Mon Sep 17 00:00:00 2001 From: Greg Miller <9447643+devjgm@users.noreply.github.com> Date: Fri, 2 Aug 2019 12:21:07 -0400 Subject: [PATCH 19/19] removed workspace_status_command; bazel builds never know git commit --- .bazelrc | 2 -- bazel/workspace_status.sh | 24 ------------------------ google/cloud/spanner/BUILD | 3 +-- 3 files changed, 1 insertion(+), 28 deletions(-) delete mode 100755 bazel/workspace_status.sh diff --git a/.bazelrc b/.bazelrc index faab31ef..8a1133e9 100644 --- a/.bazelrc +++ b/.bazelrc @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -build --workspace_status_command=bazel/workspace_status.sh - # Clang Sanitizers, use with (for example): # # --client_env=CXX=clang++ --client_env=CC=clang --config asan diff --git a/bazel/workspace_status.sh b/bazel/workspace_status.sh deleted file mode 100755 index a1c029f2..00000000 --- a/bazel/workspace_status.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# This script is meant to be run as bazel's `--workspace_status_command=` -# command. It should output space-separated "KEY value" pairs that bazel will -# store in the file bazel-out/stable-status.txt, which can be accessed from -# genrules(). For more info, see: -# https://docs.bazel.build/versions/master/user-manual.html#flag--workspace_status_command - -readonly commit="$(git rev-parse --short HEAD 2> /dev/null || echo unknown)" -echo "STABLE_GIT_COMMIT ${commit}" diff --git a/google/cloud/spanner/BUILD b/google/cloud/spanner/BUILD index 33513131..71dbe1ca 100644 --- a/google/cloud/spanner/BUILD +++ b/google/cloud/spanner/BUILD @@ -23,7 +23,7 @@ genrule( srcs = ["internal/build_info.cc.in"], outs = ["internal/build_info.cc"], cmd = """ -V=$$(grep STABLE_GIT_COMMIT bazel-out/stable-status.txt | cut -f2 -d' '); +V="unknown"; CC_VERSION=$$($(location //bazel:compiler_version.sh) $(CC)); CC_ID=$$($(location //bazel:compiler_id.sh) $(CC)); sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ @@ -33,7 +33,6 @@ sed -e "s;@CMAKE_CXX_COMPILER_ID@;$${CC_ID};" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE@;%s;" \ -e "s;@GOOGLE_CLOUD_CPP_SPANNER_BUILD_METADATA@;$${V};" < $< > $@ """ % (GOOGLE_CLOUD_CPP_SPANNER_IS_RELEASE), - stamp = 1, toolchains = [ "@bazel_tools//tools/cpp:current_cc_toolchain", "@bazel_tools//tools/cpp:cc_flags",