Личный опыт разработки ПО

Сборник рецептов

Автоматическое добавление версии билда в код с помощью CMake

комментариев 5

Очень удобно всегда знать какой конкретно версии та или иная сборка проекта. Для этого обычно вводят номер версии, состоящий из нескольких цифр. Я являюсь сторонником структуры состоящей из 4 цифр, вида:

Именование Смысл
Major Изменение этого поля указывает на то, что изменения функционала весьма существенные. Возможно даже была утрачена совместимость по файлам данных и протоколам.
Minor Указывает, что версия с большим значением этого поля, обладает большим функционалом.
Patch Значение изменяется при выпуске новых версий, которые содержат исправления.
Build Удобно для внутреннего использования, чтобы ссылаться на одну и ту же версию кода.

 

Все вместе это и формирует полное именование версии (Major.Minor.Pathch.Build):

4.6.12.589

Некоторые используют в качестве build уникальное числовое значение, которое увеличивается каждый раз, например, при ночной сборке. Я считаю, что никакого смысла в этом нет – гораздо удобнее привязать данный номер к ревизии в репозитории. Я использую Subversion и CMake, поэтому продемонстрирую как можно автоматизировать проставлении версии билда с этими инструментами.

Первое – необходимо добавить заголовочный файл в проект (например, version.h):

#include <string>
 
#include <boost/cstdint.hpp>
 
namespace Version
{
	const std::string& AsText();
	boost::uint64_t AsNumber();
}

Здесь находится простой интерфейс, через который из программы можно получить номер полной версии в текстовом виде или в виде уникального целочисленного идентификатора.

Теперь приведу содержимое version.cpp:

#include <boost/format.hpp>
 
#include "../version.h"
 
namespace
{
	const boost::uint8_t MAJOR = 4;
	const boost::uint16_t MINOR = 6;
	const boost::uint16_t PATCH = 12;
	const boost::uint32_t BUILD = 589; // Это значение будет изменено автоматически
}
 
const std::string& Version::AsText()
{
	static const std::string text = boost::str(boost::format("%1%.%2%.%3%.%4%") %
		static_cast<unsigned>(MAJOR) % MINOR % PATCH % BUILD);
 
	return text;
}
 
boost::uint64_t Version::AsNumber()
{
	BOOST_STATIC_ASSERT(BUILD < 0xFFFFFF);
 
	using namespace boost;
	const size_t size = sizeof(uint64_t);
 
	static const boost::uint64_t number =
		(static_cast<uint64_t>(MAJOR) 
			<< (size - sizeof(MAJOR)) * 8) |
		(static_cast<uint64_t>(MINOR) 
			<< (size - sizeof(MAJOR) - sizeof(MINOR)) * 8) |
		(static_cast<uint64_t>(PATCH) 
			<< (size - sizeof(MAJOR) - sizeof(MINOR) - sizeof(PATCH)) * 8) |
		BUILD;
 
	return number;
}

Здесь все тривиально и, думаю, не требует комментариев. Последнее, что осталось – механизм изменения значения BUILD, на номер ревизии в репозитории. С этим отлично справится CMake, просто добавьте в CMakeLists.txt следующий код:

set (VERSION_FILE ../common/sources/version.cpp)
 
find_package (Subversion REQUIRED)
Subversion_WC_INFO (${PROJECT_SOURCE_DIR} Repo)
file (READ ${VERSION_FILE} OLD_CODE)
foreach (LINE ${OLD_CODE})
	string (REGEX MATCH "BUILD = ([0-9]+)" BUILD_NUMBER ${LINE})
	if (BUILD_NUMBER)
		string (REGEX REPLACE "[0-9]+$" ${Repo_WC_REVISION} LINE ${LINE})
	endif ()
	set (NEW_CODE ${NEW_CODE} ${LINE})
endforeach (LINE)
file (WRITE ${VERSION_FILE} "${NEW_CODE}")

 

Единственная тонкость в скрипте в последней строке, а конкретней – кавычки в "${NEW_CODE}", без них будут убраны все “;”.

23rd Июнь 2012
15:31

Рубрика: C++,CMake,Инструменты,Сборка

Метки: ,

5 комментариев к 'Автоматическое добавление версии билда в код с помощью CMake'

Подписаться на комментарии по RSS или TrackBack.

  1. Версия программы — настолько распространенная и обыденная вещь, что немного странно отсутствие в интернете вменяемой информации об автоматизации этого процесса…

    P.S. Максим, кинул вам на почту немного своего опыта по решению этой проблемы. Содержимое довольно весомое, чтобы выкладывать его в комментарии. Проведите литературную обработку и добавьте в статью. Думаю, будет не лишним.

    Александр

    29 июня 12 16:05

  2. Спасибо, интересная информация.

  3. Одна незадача со скриптом — привязан на Subversion и предполагает, что все изменения заккомитены.
    Во время повального увлечения Git-ом, нужно либо задавать BUILD_NUMBER из командной строки, либо делать его из текущего времени.

    Sergei Nikulov

    29 мая 13 22:36

  4. А зачем boost здесь? Со стандартной библиотекой шаблонов (STL) не получается?

    McAaron

    16 ноября 13 14:00

  5. Скриптование на cmake лично мне не очень нравится, правда иногда сталкиваюсь. Но более красивое решение думается configure_file

    Konstantin Burlachenko

    12 января 16 3:16

Оставить комментарий