Автоматическое увеличение номера сборки в Qt Creator - PullRequest
18 голосов
/ 13 сентября 2009

Я хотел бы иметь переменную (или #define) в исходном коде C ++, которая будет увеличиваться при каждом использовании Qt Creator для создания исходного кода. Есть ли способ сделать это, какой-нибудь плагин Qt Creator или что-то подобное? Если есть способ сделать это, если я использую «make» в командной строке для сборки?

Ответы [ 5 ]

18 голосов
/ 13 сентября 2009

В вашем .pro-файле вы можете создать переменную, содержащую результаты программы командной строки. Затем вы можете использовать это для создания определения.

BUILDNO = $$(command_to_get_the_build_number)
DEFINES += BUILD=$${BUILDNO}

Если вы хотите просто увеличить число, вы можете использовать довольно простой скрипт:

#!/bin/bash
number=`cat build_number`
let number += 1
echo "$number" | tee build_number #<-- output and save the number back to file

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

7 голосов
/ 03 июля 2013

Эквивалент Windows для улучшенного решения Joerg Beutel https://stackoverflow.com/a/5967447/1619432:

.pro:

build_nr.commands = build_inc.bat
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr

HEADERS  += build.h

build_inc.bat:

@echo off 
set /p var= <build.txt 
set /a var= %var%+1 
echo %var% >build.txt
echo #define BUILD %var% >build.h
echo %var%

Использование

#include "build.h"
...
qDebug() << "Build number:" << BUILD;
7 голосов
/ 11 мая 2011

Как я уже писал после некоторого тестирования, я обнаружил, что в оригинальном решении есть проблема, поскольку номер версии не обновляется каждый раз, когда выполняется новая сборка. Во многих случаях я редактировал исходный файл, запускал сборку, но все равно получал тот же номер сборки ... Процесс сборки просто решил, что ничего не изменилось, и пропустил шаг, который бы обновил номер сборки. Сначала я попытался найти способ заставить этот шаг, но не смог понять это. Наконец я решил пойти другим путем. Теперь я использую скрипт для генерации заголовочного файла build_number.h, который содержит #define BUILD с обновленным номером позади. Так что скрипт Calebs теперь немного модифицирован (build_number.sh):

#!/bin/bash
number=`cat build_number`
let number++
echo "$number" | tee build_number #<-- output and save the number back to file
echo "#define BUILD ""$number" | tee ../MyProject/build_number.h

Инкрементное число все еще сохраняется в файле с именем build_number. Я мог бы избежать третьего файла, проанализировав сгенерированный заголовочный файл по числу, но решил отказаться от него. Обратите внимание, что скрипт и сгенерированный заголовок находятся в каталоге проектов, а файл build_number находится в каталоге сборки. Это не идеально, но я могу жить с этим.

Для того, чтобы собрать вещи, теперь есть еще кое-что сделать. Сначала сгенерированный заголовочный файл необходимо добавить в проект в Qt Designer ... Щелкните правой кнопкой мыши по заголовочным файлам и выберите "Добавить существующий файл". Во-вторых, он должен быть включен в C ++-файл, в который осуществляется доступ к определению BUILD внутри ... #include "build_number.h" ... и, наконец, необходимо добавить некоторые дополнения в файл проекта (MyProject.pro). Обратите внимание, что я удалил материал из решения Calebs, поэтому мы начинаем с нуля здесь:

build_nr.commands = ../MyProject/build_number.sh
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr

Эти строки (я поставил их перед разделом HEADERS) заставляют выполнить скрипт, который читает последний номер сборки из build_number, увеличивает его, записывает обратно, а также генерирует обновленную версию файла build_number.h , Поскольку это часть исходного кода проекта, новое значение каждый раз связывается с кодом.

Есть одна вещь, которую стоит упомянуть - сейчас процесс строительства никогда при том мнении, что ничего не изменилось. Таким образом, даже если вы оставите свой код без изменений, новый запуск make сгенерирует новый номер версии и создаст новый двоичный файл. Старое решение оставило число, когда код изменился, это новое решение вызывает новую сборку, даже если исходный код не изменился, так как я принудительно изменяю этот заголовочный файл. Можно было бы предпочесть что-то промежуточное, но поскольку заголовок включен только в одном месте, перестройка выполняется очень быстро и не причиняет большого вреда. Но все же, если кто-то знает, как получить лучшее из обоих миров, пожалуйста, сообщите. По крайней мере, теперь у меня не будет двух разных двоичных файлов с одинаковым номером версии.

4 голосов
/ 07 мая 2011

Предложение Калеба великолепно, но в моем случае это не сработало "из коробки". Вместо этого я получил некоторые ошибки, и для их исправления потребовалось некоторое чтение. Изменения очень незначительные. Я использовал Qt 4.7 в Ubuntu Linux ... Первое изменение, если вы можете в это поверить, было в сценарии оболочки, чтобы перейти от let number += 1 к let number++ ... Я обычно использую / программирую Windoze, так что я могу ' Это не объясняет, но когда я запускаю скрипт из командной строки (приглашение оболочки) в исходном случае, я получаю сообщения об ошибках, в измененном случае все идет хорошо и возвращаются увеличивающиеся числа ...

Поскольку Caleb сообщает об этом не полностью - я использовал build_number.sh в качестве имени сценария оболочки и создал другой файл с именем build_number (без .sh) и поместил только ноль внутри, ничего больше.

Последняя и самая неприятная ошибка была исправлена ​​заменой BUILDNO = $$(command_to_get_the_build_number) на BUILDNO = $$system(./build_number.sh) в файле проекта Qt. Обратите внимание на system после $$ и обязательный ./ перед именем файла. Последнее элементарно для обычного пользователя Linux, но не так сильно для пользователя Windows.

Надеюсь, это сделает его более понятным для людей, впервые знакомых со всем этим, таких как я. Вы можете прочитать больше в разделе справки Qt Designer, если вы ищете qmake, включая ссылку на функцию, Расширенное использование и т. Д.

О, последнее слово ... Мне также пришлось изменить DEFINES += -DBUILD=$${BUILDNO} на DEFINES += BUILD=$${BUILDNO}, так что -D пропал. Внутри вашего кода C ++ вы будете использовать BUILD, как если бы вы написали #define BUILD 1234 в верхней части файла.

1 голос
/ 08 ноября 2016

Вот решение для Win7, которое я придумал на основе решения handle . Это решение также заставляет Windows выдавать свою версию #, когда вы щелкаете правой кнопкой мыши по цели и выбираете Свойства | Подробности. Он работает в Win7 и, возможно, в самых ранних версиях.

Хорошо, вы делаете свой build_inc.bat:

@echo off
copy /b myapp.rc +,,
set /p var= <build.txt 
set /a var= %var%+1 
echo %var% >build.txt
echo #define BUILD %var% >build.h

и поместите его в папку proj. (copy /b myapp.rc +,, непостижимо для Microsoft - eese для «прикосновения» - для обновления метки времени файла.) Пока все хорошо - и что? !!

Эта часть не обязательна, если вам не нужна версия, закодированная в двоичном файле. Создайте файл .rc, например ::

#include "build.h"

1 VERSIONINFO
FILEFLAGS 32
FILEVERSION 1, 0, BUILD, 0
PRODUCTVERSION 1, 0, BUILD, 0
FILEOS 4
FILETYPE 1

{
    BLOCK "StringFileInfo"
    {
        BLOCK "040904B0"
        {
            VALUE "FileDescription", "program"
            VALUE "OriginalFilename", "program.exe"
            VALUE "CompanyName", "you"
            VALUE "FileVersion", "Release"
            VALUE "LegalCopyright", "Copyright (c) 2016, you, fool!"
            VALUE "ProductName", "Yer proggie"
            VALUE "ProductVersion", "Release"
        }
    }
    BLOCK "VarFileInfo"
    {
        VALUE "Translation", 0x0409, 0x04B0
    }
}

Более полная версия доступна здесь: Управление версиями DLL . Кстати: он не будет работать без блока VarFileInfo. Этот .rc используется для таких вещей, как щелчок правой кнопкой мыши и получение этой информации в Свойствах | Подробности. У меня есть и файл M $ .rc для этой информации, и значок приложения, и я добавляю другие ресурсы в Qt Creator в разделе Ресурсы.

Не так уж и необязательно: вот часть, которую я потратил некоторое время, чтобы найти. В Qt Creator, открыв yer proj, щелкните по маленькому значку компьютера и переведите его в режим выпуска. Нажмите на «Проекты». Нажмите «Добавить шаг сборки», выберите «Пользовательский шаг процесса» и нажимайте на значок шляпы «^», пока он не окажется вверху списка. Допустим, вы назвали yer .rc, "myapp.rc". Сделайте шаг сборки следующим образом:

Command: cmd.exe
Arguments:/c build_inc.bat
Working Directory: %{CurrentProject:Path}

Хотя версия на основе qmake может хорошо работать из командной строки или инструментов командной строки, вызываемых из IDE, в Qt Creator, я считаю, шаги сборки предпочтительнее. Qt Creator фактически не запускает qmake для каждой сборки; но шаги сборки выполняются при каждой сборке.

Теперь добавьте это в ваш .pro файл:

RC_FILE +=  myapp.rc

Также добавьте myapp.rc в свой проект. Он появится в разделе «Другие файлы».

Теперь восстановите. Каждая перестройка будет вызывать прикосновение к файлу ресурса, поэтому каждый раз запускается «rc». В противном случае номер сборки не будет закодирован в двоичное право. Это бежит быстро для меня. Каждая перестройка будет увеличивать это число. Я только удосужился добавить их в сборку "Release"; поэтому отладочные сборки не увеличивают это. Они просто будут использовать номер последней сборки. Я думаю, вам нужно будет запустить его один раз в релизе, чтобы избежать ошибки. Это работает без повторного запуска qmake каждый раз в Qt Creator; и каждый раз дает вам другой номер сборки. Это не вызывает никаких других перекомпиляций. У вас есть накладные расходы на запуск «rc» и связывание каждый раз, вместо того, чтобы ничего не делать, если все обновлено; но ОТО, я делаю это только для релизных сборок; вы почти всегда делаете ссылку на сборку или запускаете в любом случае; и снова «rc» - быстрый.

Необязательно: Вы можете перемещать символ препроцессора BUILD в любом месте. #. (Примечание: вы также можете добавить иконку приложения примерно так:

IDI_ICON1 ICON DISCARDABLE "Icons/myicon.ico"

Это позволяет ему отображаться в Проводнике даже до запуска файла.)

Вы также можете формально добавить "build.h" к вашему проекту в Qt Creator, включить его в файл, в котором вы хотите использовать build # in, и использовать его как строку, например, с:

#include <QDebug>
#include "build.h"

#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)

qDebug() << QString("(build ")+STR(BUILD)+")";

Я только что заметил побочный эффект: если вы сделаете это таким образом, он будет перестраиваться перед каждым запуском в Release. Я думаю, что это не так уж плохо, чтобы заплатить. Я думаю, я всегда могу скопировать среды выполнения в каталог релиза и запустить его из Проводника; или просто смириться с дополнительной компиляцией моего about.h, прогоном «rc» и ссылкой с каждым прогоном в релизе. Впрочем, я мог бы просто создать внешний инструмент для запуска его с помощью сочетания клавиш. Я, конечно, открыт для любых улучшений в этом. В настоящее время я не беспокоюсь, так как простая компиляция "about.cpp", запуск "rc" и соединение с каждым запуском занимает не очень много времени. Все-таки люди: автоматические номера сборки!

☮!

Редактировать: Необязательно: Чтобы заставить его увеличивать номер сборки только при сборке или перестройке проекта, но не при запуске (даже если сборка всегда будет происходить в Release), перейдите в Projects | Построить и запустить | Запустите, нажмите «Добавить шаг развертывания» и выберите «Шаг пользовательского процесса»:

Command: cmd.exe
Arguments: /c if exist build.old copy /y build.old build.txt
Working Directory: %{CurrentProject:Path}

Затем добавьте

copy /y build.txt build.old

после отключения @echo в файле .bat. Возможно даже создание новых шаблонов проектов, хотя и связанных с ними: Расширение руководства Qt Creator

Редактировать: теперь я заставил его работать с одним, а не с двумя пользовательскими шагами сборки.

...