diff --git a/.gitignore b/.gitignore index 247ef93a42..6987691294 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ install* *.layout CMakeFiles/ CMakeLists.txt.user - +SOURCE_DATE_EPOCH diff --git a/apps/2d-slam-demo/CAboutBox.cpp b/apps/2d-slam-demo/CAboutBox.cpp index d386d2b26c..1d310f7319 100644 --- a/apps/2d-slam-demo/CAboutBox.cpp +++ b/apps/2d-slam-demo/CAboutBox.cpp @@ -148,7 +148,7 @@ void CAboutBox::OnInit(wxInitDialogEvent& event) cout << "For bug reports or to collaborate: \n"; cout << "MRPT version: " << MRPT_getVersion() << endl; - cout << "MRPT compilation date: " << MRPT_getCompilationDate() << endl; + cout << "MRPT source timestamp: " << MRPT_getCompilationDate() << endl; cout << "Eigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl; cout << "wxWidgets version: " <\n"; cout << "MRPT version: " << MRPT_getVersion() << endl; - cout << "MRPT compilation date: " << MRPT_getCompilationDate() << endl; + cout << "MRPT source timestamp: " << MRPT_getCompilationDate() << endl; cout << "Eigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl; cout << "wxWidgets version: " <1 && !os::_strcmp(argv[1],"--version"); printf(" icp-slam-live - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); if (showVersion) return 0; // Program end printf("-------------------------------------------------------------------\n"); diff --git a/apps/icp-slam/icp-slam_main.cpp b/apps/icp-slam/icp-slam_main.cpp index 3fabf7fda5..dbc4650d74 100644 --- a/apps/icp-slam/icp-slam_main.cpp +++ b/apps/icp-slam/icp-slam_main.cpp @@ -57,7 +57,7 @@ int main(int argc, char **argv) bool showVersion = argc>1 && !os::_strcmp(argv[1],"--version"); printf(" icp-slam - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); if (showVersion) return 0; // Program end diff --git a/apps/kf-slam/kf-slam_main.cpp b/apps/kf-slam/kf-slam_main.cpp index 76b2d42952..0c23b84c23 100644 --- a/apps/kf-slam/kf-slam_main.cpp +++ b/apps/kf-slam/kf-slam_main.cpp @@ -59,7 +59,7 @@ int main(int argc, char **argv) try { printf(" kf-slam - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); printf("-------------------------------------------------------------------\n"); // Process arguments: diff --git a/apps/kinect-stereo-calib/CAboutBox.cpp b/apps/kinect-stereo-calib/CAboutBox.cpp index 4599ce64f1..a7bb18eca0 100644 --- a/apps/kinect-stereo-calib/CAboutBox.cpp +++ b/apps/kinect-stereo-calib/CAboutBox.cpp @@ -147,7 +147,7 @@ void CAboutBox::OnInit(wxInitDialogEvent& event) cout << "For bug reports or to collaborate: \n"; cout << "MRPT version: " << MRPT_getVersion() << endl; - cout << "MRPT compilation date: " << MRPT_getCompilationDate() << endl; + cout << "MRPT source timestamp: " << MRPT_getCompilationDate() << endl; cout << "Eigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl; cout << "wxWidgets version: " <1 && !os::_strcmp(argv[1],"--version"); printf(" simul-beacons - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); if (showVersion) return 0; // Program end diff --git a/apps/simul-gridmap/simul-gridmap_main.cpp b/apps/simul-gridmap/simul-gridmap_main.cpp index 330c1c7f61..d2e7587e22 100644 --- a/apps/simul-gridmap/simul-gridmap_main.cpp +++ b/apps/simul-gridmap/simul-gridmap_main.cpp @@ -76,7 +76,7 @@ int main(int argc, char ** argv) if (arg_nologo.getValue()) { printf(" simul-gridmap - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); } // Invoke method: diff --git a/apps/simul-landmarks/simul-landmarks-main.cpp b/apps/simul-landmarks/simul-landmarks-main.cpp index 1e3863dcdd..ec27d3898e 100644 --- a/apps/simul-landmarks/simul-landmarks-main.cpp +++ b/apps/simul-landmarks/simul-landmarks-main.cpp @@ -47,7 +47,7 @@ int main(int argc, char ** argv) bool showVersion = argc>1 && !os::_strcmp(argv[1],"--version"); printf(" simul-landmarks - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); if (showVersion) return 0; // Program end diff --git a/apps/track-video-features/track-video-feats_main.cpp b/apps/track-video-features/track-video-feats_main.cpp index f132e622c5..7e3dbeb926 100644 --- a/apps/track-video-features/track-video-feats_main.cpp +++ b/apps/track-video-features/track-video-feats_main.cpp @@ -369,7 +369,7 @@ int main(int argc, char **argv) try { printf(" track-video-features - Part of MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", mrpt::system::MRPT_getVersion().c_str(), mrpt::system::MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", mrpt::system::MRPT_getVersion().c_str(), mrpt::system::MRPT_getCompilationDate().c_str()); printf("-------------------------------------------------------------------\n"); // The video source: diff --git a/apps/velodyne-view/velodyne-view_main.cpp b/apps/velodyne-view/velodyne-view_main.cpp index 4d4eb4cb3a..1f103c529c 100644 --- a/apps/velodyne-view/velodyne-view_main.cpp +++ b/apps/velodyne-view/velodyne-view_main.cpp @@ -146,7 +146,7 @@ int VelodyneView(int argc, char **argv) if (!arg_nologo.isSet()) { printf(" velodyne-view - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", mrpt::system::MRPT_getVersion().c_str(), mrpt::system::MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", mrpt::system::MRPT_getVersion().c_str(), mrpt::system::MRPT_getCompilationDate().c_str()); } // Launch grabbing thread: diff --git a/cmakemodules/script_create_version_h.cmake b/cmakemodules/script_create_version_h.cmake index 7f917bf49e..00cddac4f5 100644 --- a/cmakemodules/script_create_version_h.cmake +++ b/cmakemodules/script_create_version_h.cmake @@ -7,11 +7,38 @@ SET(CMAKE_MRPT_COMPLETE_NAME "MRPT ${CMAKE_MRPT_VERSION_NUMBER_MAJOR}.${CMAKE_MR # Build a three digits version code, eg. 0.5.1 -> 051, 1.2.0 -> 120 SET(CMAKE_MRPT_VERSION_CODE "0x${CMAKE_MRPT_VERSION_NUMBER_MAJOR}${CMAKE_MRPT_VERSION_NUMBER_MINOR}${CMAKE_MRPT_VERSION_NUMBER_PATCH}") -IF (CMAKE_VERSION VERSION_GREATER 2.8.10) - STRING(TIMESTAMP CMAKE_MRPT_BUILD_DATE "%Y-%m-%d") -ELSE() - SET(CMAKE_MRPT_BUILD_DATE "") -ENDIF() +# SOURCE_DATE_EPOCH: See Specs in https://reproducible-builds.org/specs/source-date-epoch/ +# Take its value from: +# 1) The file SRC/SOURCE_DATE_EPOCH (generated by scripts creating Windows/Debian packages) +# 2) The env var "SOURCE_DATE_EPOCH" +# 3) The output from "git log -1 --pretty=%ct" +# 4) As a last resort, leave it blank, so the C++ source code will use current time. + +SET(CMAKE_SOURCE_DATE_EPOCH "") +# 1: SRC/SOURCE_DATE_EPOCH +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SOURCE_DATE_EPOCH") + FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/SOURCE_DATE_EPOCH" CMAKE_SOURCE_DATE_EPOCH LIMIT_COUNT 1) # Read only the first line +endif() +if ("" STREQUAL "${CMAKE_SOURCE_DATE_EPOCH}") + # If empty: + # 2) The env var "SOURCE_DATE_EPOCH" + if (DEFINED ENV{SOURCE_DATE_EPOCH}) + set(CMAKE_SOURCE_DATE_EPOCH "$ENV{SOURCE_DATE_EPOCH}") + else() + # 3) The output from "git log -1 --pretty=%ct" + find_package(Git QUIET) + if(GIT_FOUND) + execute_process( + COMMAND "${GIT_EXECUTABLE}" "log" "-1" "--pretty=%ct" + OUTPUT_VARIABLE CMAKE_SOURCE_DATE_EPOCH + OUTPUT_STRIP_TRAILING_WHITESPACE) + IF ($ENV{VERBOSE}) + MESSAGE(STATUS "SOURCE_DATE_EPOCH from git log: ${CMAKE_SOURCE_DATE_EPOCH}") + ENDIF() + endif() + endif() +endif() + CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/parse-files/version.h.in" "${MRPT_CONFIG_FILE_INCLUDE_DIR}/mrpt/version.h") diff --git a/cmakemodules/script_show_final_summary.cmake b/cmakemodules/script_show_final_summary.cmake index ebfc94e39e..d5edc46d11 100644 --- a/cmakemodules/script_show_final_summary.cmake +++ b/cmakemodules/script_show_final_summary.cmake @@ -62,6 +62,11 @@ MESSAGE(STATUS " Word size (32/64 bit) : ${CMAKE_MRPT_WORD_SIZE}") MESSAGE(STATUS " CMake version : " ${CMAKE_VERSION}) MESSAGE(STATUS " CMake generator : " ${CMAKE_GENERATOR}) MESSAGE(STATUS " CMake build tool : " ${CMAKE_BUILD_TOOL}) +if (UNIX) + execute_process(COMMAND "date" "-u" "-d" "@${CMAKE_SOURCE_DATE_EPOCH}" "+%Y-%m-%d" OUTPUT_VARIABLE MRPT_BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) +endif(UNIX) +MESSAGE(STATUS " MRPT SOURCE_DATE_EPOCH : " ${CMAKE_SOURCE_DATE_EPOCH} " (${MRPT_BUILD_DATE})") + MESSAGE(STATUS " Compiler : " ${CMAKE_CXX_COMPILER_ID}) if(MSVC) MESSAGE(STATUS " MSVC : " ${MSVC_VERSION}) diff --git a/libs/base/include/mrpt/system/os.h b/libs/base/include/mrpt/system/os.h index 014ed50686..1813b182da 100644 --- a/libs/base/include/mrpt/system/os.h +++ b/libs/base/include/mrpt/system/os.h @@ -141,19 +141,16 @@ namespace mrpt /** \addtogroup mrpt_system_os * @{ */ - /** Shows the message "Press any key to continue" (or other custom message) to the current standard output and returns when a key is pressed. - */ + /** Shows the message "Press any key to continue" (or other custom message) to the current standard output and returns when a key is pressed */ void BASE_IMPEXP pause(const std::string &msg = std::string("Press any key to continue...") ) MRPT_NO_THROWS; /** Clears the console window */ void BASE_IMPEXP clearConsole(); - /** Returns the MRPT compilation date - */ + /** Returns the MRPT source code timestamp, according to the Reproducible-Builds specifications: https://reproducible-builds.org/specs/source-date-epoch/ */ std::string BASE_IMPEXP MRPT_getCompilationDate(); - /** Returns a string describing the MRPT version including the SVN number. - */ + /** Returns a string describing the MRPT version */ std::string BASE_IMPEXP MRPT_getVersion(); /** Returns a const ref to a text with the same text that appears at the beginning of each MRPT file (useful for displaying the License text in GUIs) */ diff --git a/libs/base/src/system/os.cpp b/libs/base/src/system/os.cpp index 613fa35a20..d5483c4e74 100644 --- a/libs/base/src/system/os.cpp +++ b/libs/base/src/system/os.cpp @@ -154,9 +154,31 @@ void mrpt::system::registerFatalExceptionHandlers() mrpt::system::MRPT_getCompilationDate ---------------------------------------------------------------*/ #include +#include +#include +#include + string mrpt::system::MRPT_getCompilationDate() { - return string( MRPT_build_date_str ); + time_t now; + char *endptr; + const char *source_date_epoch = MRPT_SOURCE_DATE_EPOCH; + + errno = 0; + unsigned long long epoch = strtoull(source_date_epoch, &endptr, 10); + if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) || (errno != 0 && epoch == 0)) { + // Last resort: + now = time(NULL); + } + else { + now = epoch; + } + struct tm *build_time = gmtime(&now); + const int year = build_time->tm_year + 1900; + const int month = build_time->tm_mon + 1; + const int day = build_time->tm_mday; + + return mrpt::format("%i-%02i-%02i",year,month,day); } /*--------------------------------------------------------------- diff --git a/mex/apps/mex-grabber/mexgrabber.cpp b/mex/apps/mex-grabber/mexgrabber.cpp index 6f0e83fa4b..427dd9fa40 100644 --- a/mex/apps/mex-grabber/mexgrabber.cpp +++ b/mex/apps/mex-grabber/mexgrabber.cpp @@ -80,7 +80,7 @@ namespace { MEX_DEFINE(new) (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { printf(" mex-grabber - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); printf("-------------------------------------------------------------------\n"); mexplus::InputArguments input(nrhs, prhs, 1); @@ -297,7 +297,7 @@ int main(int argc, const char* argv[] ) try { printf(" MEX-grabber - Part of the MRPT\n"); - printf(" MRPT C++ Library: %s - BUILD DATE %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); + printf(" MRPT C++ Library: %s - Sources timestamp: %s\n", MRPT_getVersion().c_str(), MRPT_getCompilationDate().c_str()); printf("-------------------------------------------------------------------\n"); printf(" This is a test for Matlab MEX functionalities\n"); printf("-------------------------------------------------------------------\n"); diff --git a/parse-files/version.h.in b/parse-files/version.h.in index 3d5df11ee4..a93631b00c 100644 --- a/parse-files/version.h.in +++ b/parse-files/version.h.in @@ -6,10 +6,11 @@ #define MRPT_VERSION_H const char MRPT_version_str[] = "${CMAKE_MRPT_COMPLETE_NAME}"; -const char MRPT_build_date_str[] = "${CMAKE_MRPT_BUILD_DATE}"; - /** Version number of package in hexadecimal: * A three digits version code, eg. 0.5.1 -> 0x051, 1.2.0 -> 0x120 */ #define MRPT_VERSION ${CMAKE_MRPT_VERSION_CODE} +// See specs: https://reproducible-builds.org/specs/source-date-epoch/ +const char MRPT_SOURCE_DATE_EPOCH[] = "${CMAKE_SOURCE_DATE_EPOCH}"; + #endif diff --git a/scripts/prepare_debian.sh b/scripts/prepare_debian.sh index ea7b650202..b6b63c7bca 100755 --- a/scripts/prepare_debian.sh +++ b/scripts/prepare_debian.sh @@ -96,11 +96,19 @@ if [ -d "$MRPTSRC/.git" ]; then echo "Exporting git source tree to ${MRPT_DEBSRC_DIR}" git archive --format=tar master | tar -x -C ${MRPT_DEBSRC_DIR} + + # Generate ./SOURCE_DATE_EPOCH with UNIX time_t + SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) else echo "Copying sources to ${MRPT_DEBSRC_DIR}" cp -R . ${MRPT_DEBSRC_DIR} + + # Generate ./SOURCE_DATE_EPOCH with UNIX time_t + SOURCE_DATE_EPOCH=$(date +%s) fi +echo $SOURCE_DATE_EPOCH > ${MRPT_DEBSRC_DIR}/SOURCE_DATE_EPOCH + if [ ! -f "${MRPT_DEBSRC_DIR}/CMakeLists.txt" ]; then echo "*ERROR*: Seems there was a problem copying sources to ${MRPT_DEBSRC_DIR}... aborting script." diff --git a/scripts/prepare_release.sh b/scripts/prepare_release.sh index 9c4c0a194d..b91c4af9c8 100755 --- a/scripts/prepare_release.sh +++ b/scripts/prepare_release.sh @@ -39,11 +39,18 @@ if [ -d "$MRPTSRC/.git" ]; then echo "Exporting git source tree to ${MRPT_DEBSRC_DIR}" git archive --format=tar master | tar -x -C ${MRPT_DEBSRC_DIR} + + # Generate ./SOURCE_DATE_EPOCH with UNIX time_t + SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) else echo "Copying sources to ${MRPT_DEBSRC_DIR}" cp -R . ${MRPT_DEBSRC_DIR} + + # Generate ./SOURCE_DATE_EPOCH with UNIX time_t + SOURCE_DATE_EPOCH=$(date +%s) fi +echo $SOURCE_DATE_EPOCH > ${MRPT_DEBSRC_DIR}/SOURCE_DATE_EPOCH # Copy the MRPT book: if [ -f /Work/MyBooks/mrpt-book/mrpt-book.ps ]; @@ -87,7 +94,7 @@ echo "Creating orig zip in DOS format: mrpt-${MRPT_VERSION_STR}.zip" cd mrpt-${MRPT_VERSION_STR} bash scripts/all_files_DOS_format.sh cd .. -zip mrpt-${MRPT_VERSION_STR}.zip -r mrpt-${MRPT_VERSION_STR}/* +zip mrpt-${MRPT_VERSION_STR}.zip -q -r mrpt-${MRPT_VERSION_STR}/* rm -fr mrpt-${MRPT_VERSION_STR}