- Change updaterevision to a CMake script

The benefit to this is fairly small, but it does mean a little less work needs
to be done in the build scripts for cross compiling. The C version wasn't
especially concise so it was not obviously better in any way.
This commit is contained in:
Braden Obrzut 2020-02-02 00:14:37 -05:00 committed by Christoph Oelckers
parent d527866e6d
commit 62e9e0cbbb
8 changed files with 101 additions and 185 deletions

View file

@ -426,9 +426,9 @@ endif()
# Update gitinfo.h
add_custom_target( revision_check ALL
COMMAND updaterevision src/gitinfo.h
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/tools/updaterevision/UpdateRevision.cmake" src/gitinfo.h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS updaterevision )
)
# Libraries ZDoom needs

View file

@ -2,7 +2,6 @@ cmake_minimum_required( VERSION 2.8.7 )
add_subdirectory( re2c )
add_subdirectory( lemon )
add_subdirectory( updaterevision )
add_subdirectory( zipdir )
set( CROSS_EXPORTS ${CROSS_EXPORTS} PARENT_SCOPE )

View file

@ -1,24 +0,0 @@
cmake_minimum_required( VERSION 2.8.7 )
if( WIN32 )
if( MSVC_VERSION GREATER 1399 )
# VC 8+ adds a manifest automatically to the executable. We need to
# merge ours with it.
set( MT_MERGE ON )
else()
set( TRUSTINFO trustinfo.rc )
endif()
else( WIN32 )
set( TRUSTINFO "" )
endif()
if( NOT CMAKE_CROSSCOMPILING )
add_executable( updaterevision updaterevision.c ${TRUSTINFO} )
set( CROSS_EXPORTS ${CROSS_EXPORTS} updaterevision PARENT_SCOPE )
endif()
if( MT_MERGE )
add_custom_command(TARGET updaterevision POST_BUILD
COMMAND mt -inputresource:$<TARGET_FILE:updaterevision> -manifest ${CMAKE_CURRENT_SOURCE_DIR}/trustinfo.txt -outputresource:$<TARGET_FILE:updaterevision> -nologo
COMMENT "Embedding trustinfo into updaterevision" )
endif()

View file

@ -0,0 +1,91 @@
#!/usr/bin/cmake -P
# UpdateRevision.cmake
#
# Public domain. This program uses git commands command to get
# various bits of repository status for a particular directory
# and writes it into a header file so that it can be used for a
# project's versioning.
# Boilerplate to return a variable from a function.
macro(ret_var VAR)
set(${VAR} "${${VAR}}" PARENT_SCOPE)
endmacro()
# Populate variables "Hash", "Tag", and "Timestamp" with relevant information
# from source repository. If anything goes wrong return something in "Error."
function(query_repo_info)
execute_process(
COMMAND git describe --tags --dirty=-m
RESULT_VARIABLE Error
OUTPUT_VARIABLE Tag
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT "${Error}" STREQUAL "0")
ret_var(Error)
return()
endif()
execute_process(
COMMAND git log -1 "--format=%ai;%H"
RESULT_VARIABLE Error
OUTPUT_VARIABLE CommitInfo
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT "${Error}" STREQUAL "0")
ret_var(Error)
return()
endif()
list(GET CommitInfo 0 Timestamp)
list(GET CommitInfo 1 Hash)
ret_var(Tag)
ret_var(Timestamp)
ret_var(Hash)
endfunction()
# Although configure_file doesn't overwrite the file if the contents are the
# same we can't easily observe that to change the status message. This
# function parses the existing file (if it exists) and puts the hash in
# variable "OldHash"
function(get_existing_hash File)
if(EXISTS "${File}")
file(STRINGS "${File}" OldHash LIMIT_COUNT 1)
if(OldHash)
string(SUBSTRING "${OldHash}" 3 -1 OldHash)
ret_var(OldHash)
endif()
endif()
endfunction()
function(main)
if(NOT CMAKE_ARGC EQUAL 4) # cmake -P UpdateRevision.cmake <OutputFile>
message("Usage: ${CMAKE_ARGV2} <path to gitinfo.h>")
return()
endif()
set(OutputFile "${CMAKE_ARGV3}")
get_filename_component(ScriptDir "${CMAKE_SCRIPT_MODE_FILE}" DIRECTORY)
query_repo_info()
if(NOT Hash)
message("Failed to get commit info: ${Error}")
set(Hash "0")
set(Tag "<unknown version>")
set(Timestamp "")
endif()
get_existing_hash("${OutputFile}")
if(Hash STREQUAL OldHash)
message("${OutputFile} is up to date at commit ${Tag}.")
return()
endif()
configure_file("${ScriptDir}/gitinfo.h.in" "${OutputFile}")
message("${OutputFile} updated to commit ${Tag}.")
endfunction()
main()

View file

@ -0,0 +1,8 @@
// @Hash@
//
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define GIT_DESCRIPTION "@Tag@"
#define GIT_HASH "@Hash@"
#define GIT_TIME "@Timestamp@"

View file

@ -1,6 +0,0 @@
// This resource script is for compiling with MinGW only. Visual C++
// compilations use the manifest tool to insert the manifest instead.
#include <WinUser.h>
1 RT_MANIFEST "trustinfo.txt"

View file

@ -1,16 +0,0 @@
<!-- Ignore any warnings about Unrecognized Element "trustInfo" -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="UpdateRevision"
type="win32" />
<description>Update svnrevision.h for the ZDoom source build process.</description>
<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:security>
<ms_asmv3:requestedPrivileges>
<ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
</ms_asmv3:requestedPrivileges>
</ms_asmv3:security>
</ms_asmv3:trustInfo>
</assembly>

View file

@ -1,136 +0,0 @@
/* updaterevision.c
*
* Public domain. This program uses git commands command to get
* various bits of repository status for a particular directory
* and writes it into a header file so that it can be used for a
* project's versioning.
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
// Used to strip newline characters from lines read by fgets.
void stripnl(char *str)
{
if (*str != '\0')
{
size_t len = strlen(str);
if (str[len - 1] == '\n')
{
str[len - 1] = '\0';
}
}
}
int main(int argc, char **argv)
{
char vertag[128], lastlog[128], lasthash[128], *hash = NULL;
FILE *stream = NULL;
int gotrev = 0, needupdate = 1;
vertag[0] = '\0';
lastlog[0] = '\0';
if (argc != 2)
{
fprintf(stderr, "Usage: %s <path to gitinfo.h>\n", argv[0]);
return 1;
}
// Use git describe --tags to get a version string. If we are sitting directly
// on a tag, it returns that tag. Otherwise it returns <most recent tag>-<number of
// commits since the tag>-<short hash>.
// Use git log to get the time of the latest commit in ISO 8601 format and its full hash.
stream = popen("git describe --tags --dirty=-m && git log -1 --format=%ai*%H", "r");
if (NULL != stream)
{
if (fgets(vertag, sizeof vertag, stream) == vertag &&
fgets(lastlog, sizeof lastlog, stream) == lastlog)
{
stripnl(vertag);
stripnl(lastlog);
gotrev = 1;
}
pclose(stream);
}
if (gotrev)
{
hash = strchr(lastlog, '*');
if (hash != NULL)
{
*hash = '\0';
hash++;
}
}
if (hash == NULL)
{
fprintf(stderr, "Failed to get commit info: %s\n", strerror(errno));
strcpy(vertag, "<unknown version>");
lastlog[0] = '\0';
lastlog[1] = '0';
lastlog[2] = '\0';
hash = lastlog + 1;
}
stream = fopen (argv[1], "r");
if (stream != NULL)
{
if (!gotrev)
{ // If we didn't get a revision but the file does exist, leave it alone.
fclose (stream);
return 0;
}
// Read the revision that's in this file already. If it's the same as
// what we've got, then we don't need to modify it and can avoid rebuilding
// dependant files.
if (fgets(lasthash, sizeof lasthash, stream) == lasthash)
{
stripnl(lasthash);
if (strcmp(hash, lasthash + 3) == 0)
{
needupdate = 0;
}
}
fclose (stream);
}
if (needupdate)
{
stream = fopen (argv[1], "w");
if (stream == NULL)
{
return 1;
}
fprintf(stream,
"// %s\n"
"//\n"
"// This file was automatically generated by the\n"
"// updaterevision tool. Do not edit by hand.\n"
"\n"
"#define GIT_DESCRIPTION \"%s\"\n"
"#define GIT_HASH \"%s\"\n"
"#define GIT_TIME \"%s\"\n",
hash, vertag, hash, lastlog);
fclose(stream);
fprintf(stderr, "%s updated to commit %s.\n", argv[1], vertag);
}
else
{
fprintf (stderr, "%s is up to date at commit %s.\n", argv[1], vertag);
}
return 0;
}