@@ -239,54 +239,143 @@ function(write_version_header dir)
239
239
240
240
# Check the revision string, if it matches we fill in the required info
241
241
if (REVISION_STRING MATCHES "build-([0-9]+)-g([0-9a-f]+)(-dirty)?" )
242
- set (REVISION_GIT_TAGREF " ${CMAKE_MATCH_2} " )
242
+ set (BUILD_NUMBER ${CMAKE_MATCH_1} )
243
243
if (CMAKE_MATCH_3 )
244
- set (REVISION_STRING "${CMAKE_MATCH_1 } *" )
244
+ set (REVISION_GIT_TAGREF "${CMAKE_MATCH_2 } *" )
245
245
else ()
246
- set (REVISION_STRING "${CMAKE_MATCH_1 } " )
246
+ set (REVISION_GIT_TAGREF "${CMAKE_MATCH_2 } " )
247
247
endif ()
248
248
249
249
string (TIMESTAMP REVISION_DATE_TIME "%Y-%m-%dT%H:%M:%SZ" UTC )
250
250
else ()
251
251
message (STATUS "no git info available, cannot update version string" )
252
252
253
253
set (REVISION_GIT_TAGREF "" )
254
- set (REVISION_STRING "" )
254
+ set (BUILD_NUMBER 0 )
255
255
set (REVISION_DATE_TIME "" )
256
256
endif ()
257
257
258
258
if (VERSION_STRING_OPTION_VAR_PREFIX )
259
259
set (VAR_PREFIX "${VERSION_STRING_OPTION_VAR_PREFIX} " )
260
260
endif ()
261
261
262
- file (WRITE "${VERSION_STRING_DATA} /${file_name} .in" [[// Generated revision file
262
+ file (WRITE "${VERSION_STRING_DATA} /${file_name} .in" [[
263
+
264
+
265
+ // Generated revision file
263
266
264
267
#pragma once
265
268
266
269
#include <ostream>
267
270
268
- const char k@VAR_PREFIX@ProjectName[] = "@PROJECT_NAME@";
269
- const char k@VAR_PREFIX@VersionNumber[] = "@PROJECT_VERSION@";
270
- const char k@VAR_PREFIX@RevisionGitTag[] = "@REVISION_GIT_TAGREF@";
271
- const char k@VAR_PREFIX@RevisionInfo[] = "@REVISION_STRING@" ;
272
- const char k@VAR_PREFIX@RevisionDate[] = "@REVISION_DATE_TIME@";
271
+ constexpr const char k@VAR_PREFIX@ProjectName[] = "@PROJECT_NAME@";
272
+ constexpr const char k@VAR_PREFIX@VersionNumber[] = "@PROJECT_VERSION@";
273
+ constexpr const char k@VAR_PREFIX@RevisionGitTag[] = "@REVISION_GIT_TAGREF@";
274
+ constexpr int k@VAR_PREFIX@BuildNumber = @BUILD_NUMBER@ ;
275
+ constexpr const char k@VAR_PREFIX@RevisionDate[] = "@REVISION_DATE_TIME@";
273
276
274
- inline void write_version_string(std::ostream &os, bool verbose)
277
+ #ifndef VERSION_INFO_DEFINED
278
+ #define VERSION_INFO_DEFINED 1
279
+
280
+ #define CONCAT(a, b, c) a_ ## b ## c
281
+ #define CREATE_INSTANCE_NAME(prefix) CONCAT(k, prefix, instance)
282
+ #define CREATE_CLASS_NAME(prefix) CONCAT(version_info_, prefix, impl)
283
+
284
+ class version_info_base
275
285
{
276
- os << k@VAR_PREFIX@ProjectName << " version " << k@VAR_PREFIX@VersionNumber << std::endl;
277
- if (verbose)
286
+ public:
287
+ virtual ~version_info_base() = default;
288
+
289
+ static void write(std::ostream &os, bool verbose)
278
290
{
279
- if (k@VAR_PREFIX@RevisionInfo[0] != 0 )
291
+ for (auto inst = head(); inst != nullptr; inst = inst->m_next )
280
292
{
281
- os << "build: " << k@VAR_PREFIX@RevisionInfo << ' ' << k@VAR_PREFIX@RevisionDate << std::endl;
282
- if (k@VAR_PREFIX@RevisionGitTag[0] != 0)
283
- os << "git tag: " << k@VAR_PREFIX@RevisionGitTag << std::endl;
293
+ os << inst->m_name << " version " << inst->m_version << std::endl;
294
+
295
+ if (verbose)
296
+ {
297
+ if (inst->m_build != 0)
298
+ {
299
+ os << "build: " << inst->m_build << ' ' << inst->m_revision_date << std::endl;
300
+ if (inst->m_git_tag[0] != 0)
301
+ os << "git tag: " << inst->m_git_tag << std::endl;
302
+ }
303
+ else
304
+ os << "No revision information available" << std::endl;
305
+ }
306
+
307
+ if (inst->m_next != nullptr)
308
+ os << std::endl;
284
309
}
285
- else
286
- os << "No revision information available" << std::endl;
287
310
}
311
+
312
+ protected:
313
+
314
+ struct instance
315
+ {
316
+ const char *m_name;
317
+ const char *m_version;
318
+ const char *m_git_tag;
319
+ int m_build;
320
+ const char *m_revision_date;
321
+
322
+ instance *m_next = nullptr;
323
+ };
324
+
325
+ using instance_ptr = instance *;
326
+
327
+ static instance_ptr &head()
328
+ {
329
+ static instance_ptr s_head = nullptr;
330
+ return s_head;
331
+ }
332
+ };
333
+
334
+ template<typename T>
335
+ class version_info : public version_info_base
336
+ {
337
+ public:
338
+
339
+ using implementation_type = T;
340
+
341
+ protected:
342
+ version_info()
343
+ {
344
+ auto &s_head = head();
345
+ static instance s_next{
346
+ implementation_type::name(),
347
+ implementation_type::version(),
348
+ implementation_type::git_tag(),
349
+ implementation_type::build_number(),
350
+ implementation_type::revision_date(),
351
+ s_head };
352
+ s_head = &s_next;
353
+ }
354
+ };
355
+
356
+ inline void write_version_string(std::ostream &os, bool verbose)
357
+ {
358
+ version_info_base::write(os, verbose);
288
359
}
289
- ]] )
360
+
361
+ #endif
362
+
363
+ #define INSTANCE_NAME CREATE_INSTANCE_NAME(VAR_PREFIX)
364
+ #define CLASS_NAME CREATE_CLASS_NAME(VAR_PREFIX)
365
+
366
+ class CLASS_NAME : public version_info<CLASS_NAME>
367
+ {
368
+ public:
369
+
370
+ static constexpr const char *name() { return k@VAR_PREFIX@ProjectName; }
371
+ static constexpr const char *version() { return k@VAR_PREFIX@VersionNumber; }
372
+ static constexpr const char *git_tag() { return k@VAR_PREFIX@RevisionGitTag; }
373
+ static constexpr int build_number() { return k@VAR_PREFIX@BuildNumber; }
374
+ static constexpr const char *revision_date() { return k@VAR_PREFIX@RevisionDate; }
375
+ } INSTANCE_NAME;
376
+
377
+
378
+ ]] )
290
379
configure_file ("${VERSION_STRING_DATA} /${file_name} .in" "${dir} /${file_name} " @ONLY )
291
380
endfunction ()
292
381
0 commit comments