Add helper functions provided by cmake-modules manually now. Those should not change too often and only a small subset is needed
Separate folder for easier update and for distinction
LICENSE file included for cmake-modules files
use int for version numbers to allow unset or uninitialized version
Initialize Version object with numbers set to -1
Instead of hardcoding the version, it is now retrieved with git describe
Version now allows specifying additional version information like the git SHA1 hash and the versions since the last tag
Additional information is set to the last part of the git describe output for FSFW_VERSION now.
Version still need to be hand-updated if the FSFW is not included as a submodule for now.
Add message prefix for FSFW CMake output
- Add helper functions provided by [`cmake-modules`](https://github.com/bilke/cmake-modules) manually now. Those should not change too often and only a small subset is needed
- Separate folder for easier update and for distinction
- LICENSE file included for cmake-modules files
- use `int` for version numbers to allow unset or uninitialized version
- Initialize Version object with numbers set to -1
- Instead of hardcoding the version, it is now retrieved with `git describe`
- `Version` now allows specifying additional version information like the git SHA1 hash and the versions since the last tag
- Additional information is set to the last part of the git describe output for `FSFW_VERSION` now.
- Version still need to be hand-updated if the FSFW is not included as a submodule for now.
- Add message prefix for FSFW CMake output
Update: Added back Version class to fsfw namespace. Its a generic name, so doing this can avoid nameclashes. I have seen that Catch2 has its own Version class which is
really similar.
Update: Added back `Version` class to `fsfw` namespace. Its a generic name, so doing this can avoid nameclashes. I have seen that Catch2 has its own Version class which is
really similar.
I think an important point is to have the actual point in git history available in a produced binary for tracing faults during debugging.
On the other hand, I think relying on this for the version, which is used by downstream projects, seems a bit too ambitious for me. There seem to be some corner cases where it will not work. Also, a downstream project might not want to be sensitive to small changes which are version compliant breaking things. And lastly, it is kind of a circular reference to have the version information in the code be updated by metadata from the vcs in which it is stored (I think there is something problematic there waiting, which I can not put into words yet).
So my proposal would be the following:
Keep the exposed (via cmake) version manually defined during releases
Pull in this version into the binary as already done
Replace the FSFW_VERSION_CST_GIT_SHA1 or as it is already called in code addInfo with a vcs_info (aka version control system) which is the output of git describe at the time of compilation.
To facilitate having the right git output in every build, I suggest using add_custom_command as a PRE_BUILD step which then calls git describe and puts the output into an include header which is then used by version.cpp. As far as I can understand from the documentation this should be called whenever the actual target, the fsfw, is built and as such should always be in sync with the actual git state.
There needs to be a check if git is present on the system as well as if the code is in a git repo, but I guess/hope cmake has some provisions for that.
So, I thought about this for a while.
I think an important point is to have the actual point in git history available in a produced binary for tracing faults during debugging.
On the other hand, I think relying on this for the version, which is used by downstream projects, seems a bit too ambitious for me. There seem to be some corner cases where it will not work. Also, a downstream project might not want to be sensitive to small changes which are version compliant breaking things. And lastly, it is kind of a circular reference to have the version information in the code be updated by metadata from the vcs in which it is stored (I think there is something problematic there waiting, which I can not put into words yet).
So my proposal would be the following:
* Keep the exposed (via cmake) version manually defined during releases
* Pull in this version into the binary as already done
* Replace the `FSFW_VERSION_CST_GIT_SHA1` or as it is already called in code `addInfo` with a `vcs_info` (aka version control system) which is the output of `git describe` at the time of compilation.
To facilitate having the right git output in every build, I suggest using `add_custom_command` as a `PRE_BUILD` step which then calls `git describe` and puts the output into an include header which is then used by `version.cpp`. As far as I can understand from the documentation this should be called whenever the actual target, the fsfw, is built and as such should always be in sync with the actual git state.
There needs to be a check if git is present on the system as well as if the code is in a git repo, but I guess/hope cmake has some provisions for that.
Concerning the point that the version should still be defined manually: There is still a way to do this in the CMakeLists.txt . Currently ,it falls back to that way if retrieving with git fails.
The used CMake module already has internal checks like checking that git is installed. If we do not use this, we need add a lot of custom code, because the CMake module already handled these cases.
See the function
function(git_describe_var)if(NOTGIT_FOUND)find_package(GitQUIET)endif()get_git_head_revision(refspechash)if(NOTGIT_FOUND)set(${_var}"GIT-NOTFOUND"PARENT_SCOPE)return()endif()if(NOThash)set(${_var}"HEAD-HASH-NOTFOUND"PARENT_SCOPE)return()endif()# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND${GIT_EXECUTABLE}describe${hash}${ARGN}WORKING_DIRECTORY"${CMAKE_SOURCE_DIR}"RESULT_VARIABLEresOUTPUT_VARIABLEoutERROR_QUIETOUTPUT_STRIP_TRAILING_WHITESPACE)if(NOTresEQUAL0)set(out"${out}-${res}-NOTFOUND")endif()set(${_var}"${out}"PARENT_SCOPE)endfunction()
I don't think it is possible to use CMake functions in a PRE_BUILD command simply like this. But I can look at this, see if its maybe possible.
About the suggestion to output this into a header file: This then needs to be a valid header file, and valid C++ code. This would be best done as a configure fule. As is already done right now. The only difference is that it would be done as a pre-build command, which would re-trigger it every build instead of requiring resetting the CMake cache.
Concerning the point that the version should still be defined manually: There is still a way to do this in the `CMakeLists.txt` . Currently ,it falls back to that way if retrieving with git fails.
The used CMake module already has internal checks like checking that git is installed. If we do not use this, we need add a lot of custom code, because the CMake module already handled these cases.
See the function
```cmake
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
${GIT_EXECUTABLE}
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
```
I don't think it is possible to use CMake functions in a PRE_BUILD command simply like this. But I can look at this, see if its maybe possible.
About the suggestion to output this into a header file: This then needs to be a valid header file, and valid C++ code. This would be best done as a configure fule. As is already done right now. The only difference is that it would be done as a pre-build command, which would re-trigger it every build instead of requiring resetting the CMake cache.
# This causes the version file to be updated each time the sources change
add_custom_command(TARGET${LIB_FSFW_NAME}PRE_BUILDCOMMAND${CMAKE_COMMAND}-Etouch${FSFW_SOURCES_DIR}/FSFWVersion.h.inCOMMENT"${MSG_PREFIX} Updating FSFWVersion.h")
appears to re-trigger the version handling every time the FSFW sources change. I'm not fully sure how this works, but I guess re-touching a configure file causes CMake to execute the CMake code again which can set values in the input files. I still need to check whether the FSFWConfig.h.in is reset every time, because that would be bad.
Alright after some more testing I think I managed to create a solution for some issues.
- Update some cmake modules. The Git helpers from the `bilke` repo were obsolete, add the ones from the https://github.com/rpavlik/cmake-modules repository
The following PRE_BUILD command
```cmake
# This causes the version file to be updated each time the sources change
add_custom_command(
TARGET ${LIB_FSFW_NAME}
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E touch ${FSFW_SOURCES_DIR}/FSFWVersion.h.in
COMMENT "${MSG_PREFIX} Updating FSFWVersion.h"
)
```
appears to re-trigger the version handling every time the FSFW sources change. I'm not fully sure how this works, but I guess re-touching a configure file causes CMake to execute the CMake code again which can set values in the input files. I still need to check whether the `FSFWConfig.h.in` is reset every time, because that would be bad.
I am not happy at all with that soluton.. It is hacky and it does not work properly right now. I have a feeling the configure_file way is the least ulgy solution.
I am not happy at all with that soluton.. It is hacky and it does not work properly right now. I have a feeling the configure_file way is the least ulgy solution.
I think this is a working and possible solution. This will re-generated the auto-gen file every time source code changes and the commit tag changed. I will also update the CHANGELOG
I think this is a working and possible solution. This will re-generated the auto-gen file every time source code changes and the commit tag changed. I will also update the CHANGELOG
I have decided to go back to the previous solution using a configure file. This requires re-building th CMake cache, but I was not happy with the other solution for the following reasons
Extremely (!) hacky solution. Everybody trying to figure out what is happening in the CMakeLists.txt file is going to have a hard time
It was not possible to only re-generate the file only when it changes. CMake behaves very oddly when you leave the well-trodden path
This means the version file is always re-compiled, and all link steps are re-done for every compilation process
Other projects could re-use the version handling. I'd prefer if they follow the old way instead of taking a hacky solution which is way off the well-trodden path
At the end of the day, a fallback solution is still required so someone still needs to manually update the version number in the CMakeLists.txt. Build servers always seem to have issues using git tags (did not work on Github, does not appear to work with Jenkins either), but I like the new feature that the VSC information is written into a header file , even if a cache reset is necessary to get update it.
The hacky solution can still be found in the mueller/extend-version-class-ugly-cmake-hack branch
I have decided to go back to the previous solution using a configure file. This requires re-building th CMake cache, but I was not happy with the other solution for the following reasons
- Extremely (!) hacky solution. Everybody trying to figure out what is happening in the `CMakeLists.txt` file is going to have a hard time
- It was not possible to only re-generate the file only when it changes. CMake behaves very oddly when you leave the well-trodden path
- This means the version file is always re-compiled, and all link steps are re-done for every compilation process
- Other projects could re-use the version handling. I'd prefer if they follow the old way instead of taking a hacky solution which is way off the well-trodden path
At the end of the day, a fallback solution is still required so someone still needs to manually update the version number in the `CMakeLists.txt`. Build servers always seem to have issues using git tags (did not work on Github, does not appear to work with Jenkins either), but I like the new feature that the VSC information is written into a header file , even if a cache reset is necessary to get update it.
The hacky solution can still be found in the `mueller/extend-version-class-ugly-cmake-hack` branch
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
cmake-modulesmanually now. Those should not change too often and only a small subset is neededintfor version numbers to allow unset or uninitialized versiongit describeVersionnow allows specifying additional version information like the git SHA1 hash and the versions since the last tagFSFW_VERSIONnow.Extend version classto Extend version handling and classUpdate: Added back
Versionclass tofsfwnamespace. Its a generic name, so doing this can avoid nameclashes. I have seen that Catch2 has its own Version class which isreally similar.
So, I thought about this for a while.
I think an important point is to have the actual point in git history available in a produced binary for tracing faults during debugging.
On the other hand, I think relying on this for the version, which is used by downstream projects, seems a bit too ambitious for me. There seem to be some corner cases where it will not work. Also, a downstream project might not want to be sensitive to small changes which are version compliant breaking things. And lastly, it is kind of a circular reference to have the version information in the code be updated by metadata from the vcs in which it is stored (I think there is something problematic there waiting, which I can not put into words yet).
So my proposal would be the following:
FSFW_VERSION_CST_GIT_SHA1or as it is already called in codeaddInfowith avcs_info(aka version control system) which is the output ofgit describeat the time of compilation.To facilitate having the right git output in every build, I suggest using
add_custom_commandas aPRE_BUILDstep which then callsgit describeand puts the output into an include header which is then used byversion.cpp. As far as I can understand from the documentation this should be called whenever the actual target, the fsfw, is built and as such should always be in sync with the actual git state.There needs to be a check if git is present on the system as well as if the code is in a git repo, but I guess/hope cmake has some provisions for that.
Concerning the point that the version should still be defined manually: There is still a way to do this in the
CMakeLists.txt. Currently ,it falls back to that way if retrieving with git fails.The used CMake module already has internal checks like checking that git is installed. If we do not use this, we need add a lot of custom code, because the CMake module already handled these cases.
See the function
I don't think it is possible to use CMake functions in a PRE_BUILD command simply like this. But I can look at this, see if its maybe possible.
About the suggestion to output this into a header file: This then needs to be a valid header file, and valid C++ code. This would be best done as a configure fule. As is already done right now. The only difference is that it would be done as a pre-build command, which would re-trigger it every build instead of requiring resetting the CMake cache.
Alright after some more testing I think I managed to create a solution for some issues.
bilkerepo were obsolete, add the ones from the https://github.com/rpavlik/cmake-modules repositoryThe following PRE_BUILD command
appears to re-trigger the version handling every time the FSFW sources change. I'm not fully sure how this works, but I guess re-touching a configure file causes CMake to execute the CMake code again which can set values in the input files. I still need to check whether the
FSFWConfig.h.inis reset every time, because that would be bad.Alright, I think the other input files are reset as well.. I think another solution is required here..
This might be a better solution: https://www.mattkeeter.com/blog/2018-01-06-versioning/
I am not happy at all with that soluton.. It is hacky and it does not work properly right now. I have a feeling the configure_file way is the least ulgy solution.
Managed to make it work by using a target command instead. Performing some more tests.
I think this is a working and possible solution. This will re-generated the auto-gen file every time source code changes and the commit tag changed. I will also update the CHANGELOG
da44045377to377c3325d2I have decided to go back to the previous solution using a configure file. This requires re-building th CMake cache, but I was not happy with the other solution for the following reasons
CMakeLists.txtfile is going to have a hard timeAt the end of the day, a fallback solution is still required so someone still needs to manually update the version number in the
CMakeLists.txt. Build servers always seem to have issues using git tags (did not work on Github, does not appear to work with Jenkins either), but I like the new feature that the VSC information is written into a header file , even if a cache reset is necessary to get update it.The hacky solution can still be found in the
mueller/extend-version-class-ugly-cmake-hackbranchApproved by @mohr