Выводить отметку времени компиляции в исполняемом файле Visual C++?

Как я могу вставить информацию о метке времени компиляции в исполняемый файл, созданный с помощью Visual C++ 2005? Я хочу иметь возможность выводить что-то вроде этого при выполнении программы:

This build XXXX was compiled at dd-mm-yy, hh:mm.

где дата и время отражают время создания проекта. Они не должны изменяться при каждом последующем вызове программы, если она не перекомпилирована.

Смотрите ответ на этот вопрос: Печать даты и времени в сборке Visual Studio C++

User 22.06.2012 20:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
1
16 302
6

Ответы 6

__DATE__ 
__TIME__

предопределены как часть стандартов для C99, поэтому должны быть доступны вам. Они запускаются один раз с препроцессором.

Просто обратите внимание, что эти определения невозможно использовать с компилятором ресурсов для таких людей, как я, которые хотят добавить дату в структуру VERSIONINFO.

Skywalker13 05.01.2017 16:58

Visual C++ также поддерживает __TIMESTAMP__, что практически полностью соответствует вашим требованиям. При этом самая сложная часть меток времени сборки - поддерживать их в актуальном состоянии, что означает компиляцию файла, в котором __TIMESTAMP__ используется при каждой перестройке. Не уверен, есть ли способ настроить это в Visual C++.

Хотя это не ваш точный формат, ДАТА будет иметь формат Mmm dd yyyy, а ВРЕМЯ будет иметь формат hh: mm: ss. Вы можете создать такую ​​строку и использовать ее в любой удобной для вас процедуре печати:

const char *buildString = "This build XXXX was compiled at " __DATE__ ", " __TIME__ ".";

(Обратите внимание на другой ответ: TIMESTAMP выводит только дату / время модификации исходного файла, а не дату / время сборки.)

Думаю, предложенных решений по использованию ДАТА, ВРЕМЯ или TIMESTAMP было бы достаточно. Я действительно рекомендую заполучить сенсорную программу для включения в шаг предварительной сборки, чтобы прикоснуться к файлу, который содержит использование переменной препроцессора. Прикосновение к файлу гарантирует, что его временная метка новее, чем во время последней компиляции. Таким образом, дата / время в скомпилированном файле также изменяется при каждой перестройке.

__TIME__ и __DATE__ могут работать, однако есть некоторые сложности.

Если вы поместите эти определения в файл .h и включите определения из нескольких файлов .c / .cpp, каждый файл будет иметь другую версию даты / времени в зависимости от того, когда он был скомпилирован. Поэтому, если вы хотите использовать дату и время в двух разных местах, и они всегда должны совпадать, у вас проблемы. Если вы выполняете инкрементную сборку, один из файлов может быть перестроен, а другой - нет, что снова приводит к временным меткам, которые могут сильно отличаться.

Несколько лучший подход - создать прототипы GetBuildTimeStamp () в файле .h и поместить макросы __TIME__ и __DATE__ в файл реализации (.c / .cpp). Таким образом, вы можете использовать метки времени в нескольких местах вашего кода, и они всегда будут совпадать. Однако вам необходимо убедиться, что файл .c / .cpp перестраивается каждый раз при выполнении сборки. Если вы делаете чистые сборки, это решение может вам подойти.

Если вы выполняете инкрементные сборки, вам необходимо убедиться, что штамп сборки обновляется при каждой сборке. В Visual C++ вы можете сделать это с помощью шагов PreBuild - однако в этом случае я бы рекомендовал вместо использования __DATE__ и __TIME__ в скомпилированном файле .c / .cpp использовать текстовый файл, который читается во время выполнения во время выполнение вашей программы. Это позволяет вашему сценарию сборки быстро обновлять метку времени (не требуется компиляция или связывание) и не требует вашего шага PreBuild для понимания ваших флагов или параметров компилятора.

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

jakobengblom2 27.08.2009 15:02

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

thomthom 22.03.2014 16:46

Что ж ... для Visual C++ есть встроенный символ __ImageBase. Конкретно:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;

Вы можете проверить это во время выполнения, чтобы определить метку времени в заголовке PE:

const IMAGE_NT_HEADERS *nt_header= (const IMAGE_NT_HEADERS *)((char *)&__ImageBase + __ImageBase.e_lfanew);

И используйте nt_header->FileHeader.TimeDateStamp, чтобы получить метку времени, которая составляет секунды с 01.01.1970.

Другие вопросы по теме