diff --git a/CMakeLists.txt b/CMakeLists.txt index aacab3ea..7a2cb3b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,11 +81,6 @@ string(TIMESTAMP DATE_RESULT "%Y-%m-%d" UTC) message(STATUS "Compilation date = XX${DATE_RESULT}XX") add_definitions(-DFREEDV_BUILD_DATE="${DATE_RESULT}") -# -# generate src/version.h -# -configure_file(cmake/version.h.in src/version.h @ONLY) - # Generate custom CTest config configure_file(cmake/CTestCustom.cmake ${CMAKE_BINARY_DIR}) @@ -101,25 +96,8 @@ endif(NOT CMAKE_BUILD_TYPE) # # Find the git hash if this is a working copy. # -if(EXISTS ${CMAKE_SOURCE_DIR}/.git) - find_package(Git QUIET) - if(Git_FOUND) - execute_process( - COMMAND "${GIT_EXECUTABLE}" describe --abbrev=4 --always HEAD - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE res - OUTPUT_VARIABLE FREEDV_HASH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "freedv-gui current git hash: ${FREEDV_HASH}") - add_definitions(-DGIT_HASH="${FREEDV_HASH}") - else() - message(WARNING "Git not found. Can not determine current commit hash.") - add_definitions(-DGIT_HASH="Unknown") - endif() -else() - add_definitions(-DGIT_HASH="None") -endif() +include(cmake/CheckGit.cmake) +CheckGitSetup() # Set default build flags. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") diff --git a/USER_MANUAL.md b/USER_MANUAL.md index e8663763..44ea85f3 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -810,6 +810,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes * Add note about using XWayland on Linux. (PR #926) 3. Build system: * Update Hamlib to 4.6.3 (macOS/Windows). (PR #930) + * Reload current Git hash every time it changes. (PR #935) ## V2.0.0 June 2025 diff --git a/cmake/CheckGit.cmake b/cmake/CheckGit.cmake new file mode 100644 index 00000000..3d487463 --- /dev/null +++ b/cmake/CheckGit.cmake @@ -0,0 +1,89 @@ +set(CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}) +if (NOT DEFINED pre_configure_dir) + set(pre_configure_dir ${CMAKE_CURRENT_LIST_DIR}) +endif () + +if (NOT DEFINED post_configure_dir) + set(post_configure_dir ${CMAKE_BINARY_DIR}/generated) +endif () + +set(pre_configure_file ${pre_configure_dir}/git_version.cpp.in) +set(post_configure_file ${post_configure_dir}/git_version.cpp) + +function(CheckGitWrite git_hash) + file(WRITE ${CMAKE_BINARY_DIR}/git-state.txt ${git_hash}) +endfunction() + +function(CheckGitRead git_hash) + if (EXISTS ${CMAKE_BINARY_DIR}/git-state.txt) + file(STRINGS ${CMAKE_BINARY_DIR}/git-state.txt CONTENT) + LIST(GET CONTENT 0 var) + + set(${git_hash} ${var} PARENT_SCOPE) + endif () +endfunction() + +function(CheckGitVersion) + # Get the latest abbreviated commit hash of the working branch + execute_process( + COMMAND git describe --abbrev=4 --always HEAD + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + CheckGitRead(GIT_HASH_CACHE) + if (NOT EXISTS ${post_configure_dir}) + file(MAKE_DIRECTORY ${post_configure_dir}) + endif () + + if (NOT EXISTS ${post_configure_dir}/git_version.h) + file(COPY ${pre_configure_dir}/git_version.h DESTINATION ${post_configure_dir}) + endif() + + if (NOT GIT_HASH_CACHE) + set(GIT_HASH_CACHE "None") + endif () + + if(FREEDV_VERSION_TAG) + set(FREEDV_VERSION "${FreeDV_VERSION}-${FREEDV_VERSION_TAG}-${GIT_HASH}") + else() + set(FREEDV_VERSION "${FreeDV_VERSION}") + endif() + + # Only update the git_version.cpp if the hash has changed. This will + # prevent us from rebuilding the project more than we need to. + if (NOT ${GIT_HASH} STREQUAL ${GIT_HASH_CACHE} OR NOT EXISTS ${post_configure_file}) + # Set che GIT_HASH_CACHE variable the next build won't have + # to regenerate the source file. + CheckGitWrite(${GIT_HASH}) + + configure_file(${pre_configure_file} ${post_configure_file} @ONLY) + endif () + +endfunction() + +function(CheckGitSetup) + + add_custom_target(AlwaysCheckGit COMMAND ${CMAKE_COMMAND} + -DRUN_CHECK_GIT_VERSION=1 + -Dpre_configure_dir=${pre_configure_dir} + -Dpost_configure_file=${post_configure_dir} + -DGIT_HASH_CACHE=${GIT_HASH_CACHE} + -DFreeDV_VERSION=${FreeDV_VERSION} + -DFREEDV_VERSION_TAG=${FREEDV_VERSION_TAG} + -P ${CURRENT_LIST_DIR}/CheckGit.cmake + BYPRODUCTS ${post_configure_file} + ) + + add_library(git_version ${CMAKE_BINARY_DIR}/generated/git_version.cpp) + target_include_directories(git_version PUBLIC ${CMAKE_BINARY_DIR}/generated) + add_dependencies(git_version AlwaysCheckGit) + + CheckGitVersion() +endfunction() + +# This is used to run this function from an external cmake process. +if (RUN_CHECK_GIT_VERSION) + CheckGitVersion() +endif () diff --git a/cmake/version.h.in b/cmake/git_version.cpp.in similarity index 57% rename from cmake/version.h.in rename to cmake/git_version.cpp.in index 3e7c5ffb..ad5f3f54 100644 --- a/cmake/version.h.in +++ b/cmake/git_version.cpp.in @@ -1,16 +1,24 @@ -#ifndef FREEDV_VER_DOT_H -#define FREEDV_VER_DOT_H 1 +#include +#include "git_version.h" +const char *FREEDV_GIT_HASH = "@GIT_HASH@"; + +#if 0 #define FREEDV_VERSION_MAJOR @FreeDV_VERSION_MAJOR@ #define FREEDV_VERSION_MINOR @FreeDV_VERSION_MINOR@ #define FREEDV_VERSION_PATCH @FreeDV_VERSION_PATCH@ #define FREEDV_VERSION_SUFFIX @FreeDV_VERSION_TWEAK@ +#define FREEDV_VERSION_TAG @FREEDV_VERSION_TAG@ -#if defined(FREEDV_VERSION_TAG) -#define FREEDV_VERSION ("@FreeDV_VERSION@-" FREEDV_VERSION_TAG "-" GIT_HASH) +#if FREEDV_VERSION_TAG +#define FREEDV_VERSION ("@FreeDV_VERSION@-" FREEDV_VERSION_TAG "-" "@GIT_HASH@") //#define FREEDV_VERSION ("@FreeDV_VERSION@-" FREEDV_VERSION_TAG) #else #define FREEDV_VERSION ("@FreeDV_VERSION@") -#endif // defined(FREEDV_VERSION_TAG) +#endif // FREEDV_VERSION_TAG +#endif -#endif //FREEDV_VER_DOT_H +std::string GetFreeDVVersion() +{ + return "@FREEDV_VERSION@"; +} diff --git a/cmake/git_version.h b/cmake/git_version.h new file mode 100644 index 00000000..94cd531f --- /dev/null +++ b/cmake/git_version.h @@ -0,0 +1,31 @@ +//========================================================================== +// Name: git_hash.h +// +// Purpose: Exports the Git hash of the current version of the source code. +// Created: June 14, 2025 +// Authors: Mooneer Salem +// +// License: +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version 2.1, +// as published by the Free Software Foundation. This program is +// distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, see . +// +//========================================================================== + +#ifndef GIT_HASH_H +#define GIT_HASH_H + +#include + +extern const char* FREEDV_GIT_HASH; +std::string GetFreeDVVersion(); + +#endif // GIT_HASH_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38b3b262..a8ed014b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,9 @@ add_definitions(-DULOG_NO_COLOR) # Include third party headers include_directories(3rdparty) +# Include generated headers +include_directories(${CMAKE_BINARY_DIR}/generated) + # Compile FreeDV components add_subdirectory(audio) add_subdirectory(config) @@ -54,10 +57,10 @@ else() endif(APPLE) if(APPLE) -target_link_libraries(FreeDV fdv_audio fdv_audio_pipeline fdv_config fdv_gui_controls fdv_gui_dialogs fdv_gui_util fdv_os_wrapper fdv_rig_control fdv_reporting fdv_sox fdv_util codec2 rade opus) +target_link_libraries(FreeDV fdv_audio fdv_audio_pipeline fdv_config fdv_gui_controls fdv_gui_dialogs fdv_gui_util fdv_os_wrapper fdv_rig_control fdv_reporting fdv_sox fdv_util codec2 rade opus git_version) add_dependencies(FreeDV build_rade) else(APPLE) -target_link_libraries(freedv fdv_audio fdv_audio_pipeline fdv_config fdv_gui_controls fdv_gui_dialogs fdv_gui_util fdv_os_wrapper fdv_rig_control fdv_reporting fdv_sox fdv_util codec2 rade opus) +target_link_libraries(freedv fdv_audio fdv_audio_pipeline fdv_config fdv_gui_controls fdv_gui_dialogs fdv_gui_util fdv_os_wrapper fdv_rig_control fdv_reporting fdv_sox fdv_util codec2 rade opus git_version) add_dependencies(freedv build_rade) endif(APPLE) diff --git a/src/main.cpp b/src/main.cpp index 48425379..fa141311 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,7 @@ #include #include -#include "version.h" +#include "git_version.h" #include "main.h" #include "os/os_interface.h" #include "freedv_interface.h" @@ -437,7 +437,7 @@ bool MainApp::OnCmdLineParsed(wxCmdLineParser& parser) snprintf(prefix, prefix_size, " [%u]", ++counter); }); - log_info("FreeDV version %s starting", FREEDV_VERSION); + log_info("FreeDV version %s starting", GetFreeDVVersion().c_str()); if (!wxApp::OnCmdLineParsed(parser)) { @@ -864,7 +864,7 @@ setDefaultMode: //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= // Class MainFrame(wxFrame* pa->ent) : TopFrame(parent) //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= -MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ") + _(FREEDV_VERSION)) +MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ") + wxString::FromUTF8(GetFreeDVVersion().c_str())) { #if defined(__linux__) pthread_setname_np(pthread_self(), "FreeDV GUI"); @@ -876,7 +876,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ") // Add config file name to title bar if provided at the command line. if (wxGetApp().customConfigFileName != "") { - SetTitle(wxString::Format("%s (%s)", _("FreeDV ") + _(FREEDV_VERSION), wxGetApp().customConfigFileName)); + SetTitle(wxString::Format("%s (%s)", _("FreeDV ") + wxString::FromUTF8(GetFreeDVVersion().c_str()), wxGetApp().customConfigFileName)); } #if defined(UNOFFICIAL_RELEASE) @@ -2212,7 +2212,7 @@ void MainFrame::performFreeDVOn_() std::make_shared( wxGetApp().appConfiguration.reportingConfiguration.reportingCallsign->ToStdString(), wxGetApp().appConfiguration.reportingConfiguration.reportingGridSquare->ToStdString(), - std::string("FreeDV ") + FREEDV_VERSION); + std::string("FreeDV ") + GetFreeDVVersion()); assert(pskReporter != nullptr); wxGetApp().m_reporters.push_back(pskReporter); } @@ -3291,7 +3291,7 @@ void MainFrame::initializeFreeDVReporter_() wxGetApp().appConfiguration.reportingConfiguration.freedvReporterHostname->ToStdString(), wxGetApp().appConfiguration.reportingConfiguration.reportingCallsign->ToStdString(), wxGetApp().appConfiguration.reportingConfiguration.reportingGridSquare->ToStdString(), - std::string("FreeDV ") + FREEDV_VERSION, + std::string("FreeDV ") + GetFreeDVVersion(), receiveOnly); assert(wxGetApp().m_sharedReporterObject); diff --git a/src/ongui.cpp b/src/ongui.cpp index 3fc88e8f..d6a051f2 100644 --- a/src/ongui.cpp +++ b/src/ongui.cpp @@ -10,6 +10,7 @@ #include "main.h" +#include "git_version.h" #include "gui/dialogs/dlg_easy_setup.h" #include "gui/dialogs/dlg_filter.h" #include "gui/dialogs/dlg_audiooptions.h" @@ -351,6 +352,8 @@ void MainFrame::OnHelpAbout(wxCommandEvent& event) { wxUnusedVar(event); wxString msg; + wxString version = wxString::FromUTF8(GetFreeDVVersion().c_str()); + msg.Printf( wxT("FreeDV GUI %s\n\n") wxT("For Help and Support visit: http://freedv.org\n\n") @@ -360,7 +363,7 @@ void MainFrame::OnHelpAbout(wxCommandEvent& event) wxT("freedv-gui version: %s\n") wxT("freedv-gui git hash: %s\n") wxT("codec2 git hash: %s\n") - , FREEDV_VERSION, FREEDV_VERSION, GIT_HASH, freedv_get_hash() + , version, version, FREEDV_GIT_HASH, freedv_get_hash() ); wxMessageBox(msg, wxT("About"), wxOK | wxICON_INFORMATION, this); diff --git a/src/topFrame.h b/src/topFrame.h index ac85e909..41dab8a1 100644 --- a/src/topFrame.h +++ b/src/topFrame.h @@ -22,7 +22,7 @@ #ifndef __TOPFRAME_H__ #define __TOPFRAME_H__ -#include "version.h" +#include "git_version.h" #include #include #include