Как я могу вставить информацию о метке времени компиляции в исполняемый файл, созданный с помощью Visual C++ 2005? Я хочу иметь возможность выводить что-то вроде этого при выполнении программы:
This build XXXX was compiled at dd-mm-yy, hh:mm.
где дата и время отражают время создания проекта. Они не должны изменяться при каждом последующем вызове программы, если она не перекомпилирована.





__DATE__
__TIME__
предопределены как часть стандартов для C99, поэтому должны быть доступны вам. Они запускаются один раз с препроцессором.
Просто обратите внимание, что эти определения невозможно использовать с компилятором ресурсов для таких людей, как я, которые хотят добавить дату в структуру VERSIONINFO.
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-файл, используемый для сборки, перестраивает этот конкретный файл каждый раз, когда программа перестраивается. Это наиболее распространенное решение, которое я видел для более крупных программных проектов.
Создание функции отметки времени в файле cpp, которого я касаюсь в предварительной сборке, сработало, поскольку я хотел, чтобы она работала для инкрементных сборок. Просто наличие макроса в заголовке не обновляло метку времени в моем приложении каждый раз, когда это необходимо.
Что ж ... для 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.
Смотрите ответ на этот вопрос: Печать даты и времени в сборке Visual Studio C++