diff options
author | Aki <please@ignore.pl> | 2022-07-04 17:56:32 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-07-04 17:56:32 +0200 |
commit | dca08dd45e24119a17ad7893aedaa40f3eceee07 (patch) | |
tree | ecd7147706b94273ebb2b118218214cb44230075 /lets_not_store_versions_in_versioned_files.html | |
parent | 9651913c75269f83902ac2473c1a611dd4c77643 (diff) | |
download | ignore.pl-dca08dd45e24119a17ad7893aedaa40f3eceee07.zip ignore.pl-dca08dd45e24119a17ad7893aedaa40f3eceee07.tar.gz ignore.pl-dca08dd45e24119a17ad7893aedaa40f3eceee07.tar.bz2 |
Updated lets versions with a verbose example
Diffstat (limited to 'lets_not_store_versions_in_versioned_files.html')
-rw-r--r-- | lets_not_store_versions_in_versioned_files.html | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/lets_not_store_versions_in_versioned_files.html b/lets_not_store_versions_in_versioned_files.html index 725decd..1d83793 100644 --- a/lets_not_store_versions_in_versioned_files.html +++ b/lets_not_store_versions_in_versioned_files.html @@ -13,7 +13,7 @@ <article> <h1>Let's Not Store Versions in Versioned Files</h1> -<p class="subtitle">Published on 2022-07-02 23:33:33+02:00 +<p class="subtitle">Published on 2022-07-02 23:33:33+02:00, last modified on 2022-07-04 18:00:00+02:00 <p>It is a rather common practice to include version numbers directly in the meta files or sources that are stored inside a code repository. To list few examples: <a href="https://www.npmjs.com/">npm</a> makes it part of its regular practices, python's <a href="https://setuptools.pypa.io/">setuptools</a> usually involves various hacks, be it normal @@ -54,16 +54,54 @@ distribution, deployment, or packaging system. <p>Some of them support it better, some worse. Luckily, good chunk of them allow for arbitrary logic to be executed, so we can implement it by ourselves. Additionally, there is a good chance that the VCS provides some kind of helper for getting the human-readable tag-driven version description. In case of Git there is <b>git-describe</b>(1), which fits -this use case directly. We can just call it from CMake or setup.py and read its output. +this use case directly. We can just call it from CMake or setup.py and read its output. Very often we may be forced to +generate some full pledged files, so be ready to do it. +<h3>Example CMake Project</h3> +<p>Let's consider a C++ project built by CMake. It is intended to be packaged, but is also meant to support installing +it directly from the repository. The program itself is rather simple - it prints out its version. Every single time: +<pre> +#include <iostream> +#include "version.h" + +int main(int, char*[]) +{ + std::cout << version::full << std::endl; +} +</pre> +<p>The <i>version.h</i> is just a namespace with an extern constant. To provide an actual value for the version number, +let's write a <i>version.cpp.in</i> that will be processed by CMake to generate the actual source that will be added to +the target: +<pre> +namespace version { +const char* full = "@VERSION@"; +} +</pre> +<p>The <code>@VERSION@</code> is a pattern that is recognized by CMake's +<a href="https://cmake.org/cmake/help/latest/command/configure_file.html">configure_file</a> which we will use to +generate the actual source code that is intended for compilation just like we planned: +<pre> +add_executable(version-print main.cpp) +git_describe(VERSION) +configure_file(version.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/version.cpp @ONLY) +target_sources(version-print PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/version.cpp) +</pre> +<p>Now, CMake does not support this out-of-box sadly, so you need to implement <code>git_describe</code> yourself or get +an external module for it. There is one in +<a href="https://github.com/rpavlik/cmake-modules/blob/main/GetGitRevisionDescription.cmake">Ryan A. Pavlik's +repository</a> and I have implemented +<a href="https://git.ignore.pl/starshatter/tree/cmake/modules/GitDescribe.cmake">one for Starshatter</a> at some point. +They are rather easy and fun to write (altough there is a variety of edge cases), but it's still a bit shame that they +are not part of the core CMake. +<p>Alternatively, you can consider using a define to, well, define the version number. I use this approach with separate +file that defines the variable for the sake of dependency checks and recompilation. +<h2>Final Thoughts</h2> <p>Of course, a full-pledged support would be way nicer and stable, but surprisingly, we're not there yet. <p>Well, some of us are. To contrast the list of bad examples consider Go programming language, which recommends this method of versioning. Interestingly, it also uses code repositories as a form of package distribution, so any arguments saying that file with a version is needed because the repository is used as a means of distribution are baseless. <p>What to take away from this post? Next time when you will start a project, consider keeping meaningful version only in the VCS. If your building/distribution/whatever-else system does not support it fully out-of-box - try implementing -it. Once you have a working implementation - push it upstream. For instance, there are CMake modules that handle it, -but they are external and not part of main CMake for whatever reason. It would be much better to have it standardized -and part of the tool. Who knows, maybe in some time we might be able to have a consistent support in all across the -ecosystem. As for now, back to experimenting, and until next time! +it. Once you have a working implementation - push it upstream. Who knows, maybe in some time we might be able to have a +consistent support in all across the ecosystem. As for now, back to experimenting, and until next time! </article> <script src="https://stats.ignore.pl/track.js"></script> |