diff --git a/CMakeModules/VersionUtils.cmake b/CMakeModules/VersionUtils.cmake new file mode 100644 index 00000000000..d4ef7b0d561 --- /dev/null +++ b/CMakeModules/VersionUtils.cmake @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.5) + +function(GENERATE_VERSION_METADATA) + # Execute `git` to grab the corresponding data. + execute_process( + COMMAND ${GIT_EXEC} rev-parse HEAD + WORKING_DIRECTORY ${SRC_DIR} + OUTPUT_VARIABLE V_HASH + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE ) + execute_process( + COMMAND ${GIT_EXEC} diff --quiet + WORKING_DIRECTORY ${SRC_DIR} + RESULT_VARIABLE V_DIRTY + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE ) + + # If `V_DIRTY` is equal to 1, we know that the repository is dirty and vice versa. + if(${V_DIRTY}) + set(V_DIRTY "true") + else() + set(V_DIRTY "false") + endif() + + # Define the proper version metadata for the file `version_impl.cpp.in`. + set(_VERSION_MAJOR_ ${V_MAJOR}) + set(_VERSION_MINOR_ ${V_MINOR}) + set(_VERSION_PATCH_ ${V_PATCH}) + set(_VERSION_SUFFIX_ ${V_SUFFIX}) + set(_VERSION_HASH_ ${V_HASH}) + set(_VERSION_DIRTY_ ${V_DIRTY}) + + # Modify and substitute the `.cpp.in` file for a `.cpp` in the build directory. + configure_file( + ${CUR_SRC_DIR}/src/version_impl.cpp.in + ${CUR_BIN_DIR}/src/version_impl.cpp + @ONLY ) +endfunction(GENERATE_VERSION_METADATA) + +GENERATE_VERSION_METADATA() diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 54bb2f80e09..c639743f317 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory( wasm-jit ) add_subdirectory( appbase ) add_subdirectory( chain ) add_subdirectory( testing ) +add_subdirectory( version ) #turn tools&tests off; not needed for library build set(BUILD_TESTS OFF CACHE BOOL "Build GTest-based tests") diff --git a/libraries/version/CMakeLists.txt b/libraries/version/CMakeLists.txt new file mode 100644 index 00000000000..239c479d92b --- /dev/null +++ b/libraries/version/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.5) +project(Version) + +# Define the version metadata by default, in case `git` cannot be found. +set(_VERSION_MAJOR_ "unknown") +set(_VERSION_MINOR_ "") +set(_VERSION_PATCH_ "") +set(_VERSION_SUFFIX_ "") +set(_VERSION_HASH_ "") +set(_VERSION_DIRTY_ "") + +# Construct the library target. +add_library( + version + "${CMAKE_CURRENT_SOURCE_DIR}/src/version.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/src/version_impl.cpp") + +# Make dependencies visible to the given target library to be constructed. +target_include_directories( + version + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/" ) + +# Create a custom target to update the version metadata upon every build. +find_package(Git) +if(EXISTS ${CMAKE_SOURCE_DIR}/.git AND ${GIT_FOUND}) + add_custom_target( + evaluate_every_build ALL + COMMAND ${CMAKE_COMMAND} -DGIT_EXEC=${GIT_EXECUTABLE} + -DCUR_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR} + -DCUR_SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} + -DSRC_DIR=${CMAKE_SOURCE_DIR} + -DV_MAJOR=${VERSION_MAJOR} + -DV_MINOR=${VERSION_MINOR} + -DV_PATCH=${VERSION_PATCH} + -DV_SUFFIX=${VERSION_SUFFIX} + -P ${CMAKE_SOURCE_DIR}/CMakeModules/VersionUtils.cmake + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/src/version_impl.cpp + COMMENT "Updating version metadata..." VERBATIM ) + + # Create a dependency for the given library target. + add_dependencies(version evaluate_every_build) +else() + # Modify and substitute the `.cpp.in` file for a `.cpp` in the build directory. + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/version_impl.cpp.in + ${CMAKE_CURRENT_BINARY_DIR}/src/version_impl.cpp + @ONLY ) +endif() diff --git a/libraries/version/include/eosio/version/version.hpp b/libraries/version/include/eosio/version/version.hpp new file mode 100644 index 00000000000..d9bf85f709d --- /dev/null +++ b/libraries/version/include/eosio/version/version.hpp @@ -0,0 +1,18 @@ +/** + * @file version.hpp + * @copyright defined in eos/LICENSE + */ + +#pragma once + +#include // std::string + +namespace eosio { namespace version { + + ///< Grab the basic version information of the client; example: `v1.8.0-rc1` + const std::string& version_client(); + + ///< Grab the full version information of the client; example: `v1.8.0-rc1-7de458254[-dirty]` + const std::string& version_full(); + +} } diff --git a/libraries/version/src/version.cpp b/libraries/version/src/version.cpp new file mode 100644 index 00000000000..16a23995969 --- /dev/null +++ b/libraries/version/src/version.cpp @@ -0,0 +1,20 @@ +/** + * @file version.cpp + * @copyright defined in eos/LICENSE + */ + +#include "version_impl.hpp" + +namespace eosio { namespace version { + + const std::string& version_client() { + static const std::string version{_version_client()}; + return version; + } + + const std::string& version_full() { + static const std::string version{_version_full()}; + return version; + } + +} } diff --git a/libraries/version/src/version_impl.cpp.in b/libraries/version/src/version_impl.cpp.in new file mode 100644 index 00000000000..6a45c1dff1f --- /dev/null +++ b/libraries/version/src/version_impl.cpp.in @@ -0,0 +1,45 @@ +/** + * @file version_impl.cpp.in + * @copyright defined in eos/LICENSE + * \warning This file is machine generated. DO NOT EDIT. See version_impl.cpp.in for changes. + */ + +#include "version_impl.hpp" + +namespace eosio { namespace version { + + const std::string version_major {"@_VERSION_MAJOR_@" }; + const std::string version_minor {"@_VERSION_MINOR_@" }; + const std::string version_patch {"@_VERSION_PATCH_@" }; + const std::string version_suffix{"@_VERSION_SUFFIX_@"}; + const std::string version_hash {"@_VERSION_HASH_@" }; + const bool version_dirty { @_VERSION_DIRTY_@ }; + + std::string _version_client() { + if (version_major == "unknown") { + std::string version{"unknown"}; + return version; + } + else { + std::string version{'v' + version_major + '.' + version_minor + '.' + version_patch + '-' + version_suffix}; + return version; + } + } + + std::string _version_full() { + if (version_major == "unknown") { + std::string version{"unknown"}; + return version; + } + else { + std::string version{'v' + version_major + '.' + version_minor + '.' + version_patch + '-' + version_suffix + '-' + version_hash}; + + if (version_dirty == true) { + version += "-dirty"; + } + + return version; + } + } + +} } diff --git a/libraries/version/src/version_impl.hpp b/libraries/version/src/version_impl.hpp new file mode 100644 index 00000000000..8266383a417 --- /dev/null +++ b/libraries/version/src/version_impl.hpp @@ -0,0 +1,18 @@ +/** + * @file version_impl.hpp + * @copyright defined in eos/LICENSE + */ + +#pragma once + +#include // std::string + +namespace eosio { namespace version { + + ///< Helper function for `version_client()` + std::string _version_client(); + + ///< Helper function for `version_full()` + std::string _version_full(); + +} } diff --git a/programs/cleos/CMakeLists.txt b/programs/cleos/CMakeLists.txt index 0787c5fe937..cc7cf865680 100644 --- a/programs/cleos/CMakeLists.txt +++ b/programs/cleos/CMakeLists.txt @@ -10,23 +10,6 @@ if( GPERFTOOLS_FOUND ) list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) endif() -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../.git) - find_package(Git) - if(GIT_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../.." - OUTPUT_VARIABLE "cleos_BUILD_VERSION" - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "Git commit revision: ${cleos_BUILD_VERSION}") - else() - set(cleos_BUILD_VERSION 0) - endif() -else() - set(cleos_BUILD_VERSION 0) -endif() - find_package(Intl REQUIRED) set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) @@ -36,7 +19,7 @@ configure_file(config.hpp.in config.hpp ESCAPE_QUOTES) target_include_directories(${CLI_CLIENT_EXECUTABLE_NAME} PUBLIC ${Intl_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries( ${CLI_CLIENT_EXECUTABLE_NAME} - PRIVATE appbase chain_api_plugin producer_plugin chain_plugin http_plugin eosio_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ${Intl_LIBRARIES} ) + PRIVATE appbase version chain_api_plugin producer_plugin chain_plugin http_plugin eosio_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ${Intl_LIBRARIES} ) copy_bin( ${CLI_CLIENT_EXECUTABLE_NAME} ) diff --git a/programs/cleos/config.hpp.in b/programs/cleos/config.hpp.in index d9d5f45b1de..3441d9cd42d 100644 --- a/programs/cleos/config.hpp.in +++ b/programs/cleos/config.hpp.in @@ -6,9 +6,8 @@ #pragma once namespace eosio { namespace client { namespace config { - constexpr char version_str[] = "${cleos_BUILD_VERSION}"; - constexpr char locale_path[] = "${LOCALEDIR}"; - constexpr char locale_domain[] = "${LOCALEDOMAIN}"; - constexpr char key_store_executable_name[] = "${KEY_STORE_EXECUTABLE_NAME}"; - constexpr char node_executable_name[] = "${NODE_EXECUTABLE_NAME}"; -}}} + constexpr char locale_path[] {"${LOCALEDIR}" }; + constexpr char locale_domain[] {"${LOCALEDOMAIN}" }; + constexpr char key_store_executable_name[]{"${KEY_STORE_EXECUTABLE_NAME}"}; + constexpr char node_executable_name[] {"${NODE_EXECUTABLE_NAME}" }; +} } } diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index 36c3be1900a..03c8917ffce 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -93,6 +93,8 @@ Usage: ./cleos create account [OPTIONS] creator name OwnerKey ActiveKey #include #include +#include + #pragma push_macro("N") #undef N @@ -2402,8 +2404,12 @@ int main( int argc, char** argv ) { auto version = app.add_subcommand("version", localized("Retrieve version information"), false); version->require_subcommand(); - version->add_subcommand("client", localized("Retrieve version information of the client"))->set_callback([] { - std::cout << localized("Build version: ${ver}", ("ver", eosio::client::config::version_str)) << std::endl; + version->add_subcommand("client", localized("Retrieve basic version information of the client"))->set_callback([] { + std::cout << eosio::version::version_client() << '\n'; + }); + + version->add_subcommand("full", localized("Retrieve full version information of the client"))->set_callback([] { + std::cout << eosio::version::version_full() << '\n'; }); // Create subcommand