1include (CMakeParseArguments)
2
3set (_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
4
5# generate_product_version() function
6#
7# This function uses VersionInfo.in template file and VersionResource.rc file
8# to generate WIN32 resource with version information and general resource strings.
9#
10# Usage:
11#   generate_product_version(
12#     SomeOutputResourceVariable
13#     NAME MyVersinedTarget
14#     ICON ${PATH_TO_ICON}
15#     VERSION_MAJOR 2
16#     VERSION_MINOR 3
17#     VERSION_PATCH 1
18#     VERSION_REVISION sha1
19#   )
20#
21# You can use generated resource for your executable targets:
22#   add_executable(target-name ${target-files} ${SomeOutputResourceVariable})
23#   add_library (target-name SHARED ${target-files} ${SomeOutputResourceVariable})
24#
25# You can specify resource strings in arguments:
26#   NAME               - name of executable (no defaults, ex: Microsoft Word)
27#   BUNDLE             - bundle (${PROJECT_NAME} or ${NAME} is default, ex: Microsoft Office)
28#   ICON               - path to application icon, default: ${CMAKE_SOURCE_DIR}/icons/windows-icons/${NAME}.ico
29#   VERSION_MAJOR      - default: 1
30#   VERSION_MINOR      - deafult: 0
31#   VERSION_PATCH      - deafult: 0
32#   VERSION_REVISION   - deafult: 0
33#   VENDOR_NAME        - your vendor name, default: ${PROJECT_VENDOR}
34#   LEGAL_COPYRIGHT    - default: ${PROJECT_COPYRIGHT}
35#   COMMENTS           - default: ${PROJECT_DESCRIPTION}
36#   ORIGINAL_FILENAME  - default: ${NAME}
37#   INTERNAL_NAME      - default: ${NAME}
38#   FILE_DESCRIPTION   - default: ${COMMENTS}
39function(generate_version_info outfiles)
40  set (options)
41  set (oneValueArgs
42    NAME
43    BUNDLE
44    ICON
45    VERSION_MAJOR
46    VERSION_MINOR
47    VERSION_PATCH
48    VERSION_REVISION
49    VENDOR_NAME
50    LEGAL_COPYRIGHT
51    COMMENTS
52    ORIGINAL_FILENAME
53    INTERNAL_NAME
54    FILE_DESCRIPTION)
55  set (multiValueArgs)
56  cmake_parse_arguments(PRODUCT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
57
58  if (NOT PRODUCT_BUNDLE)
59    if (PROJECT_NAME)
60      set (PRODUCT_BUNDLE "${PROJECT_NAME}")
61    else ()
62      set (PRODUCT_BUNDLE "${PRODUCT_NAME}")
63    endif ()
64  endif()
65
66  if (NOT PRODUCT_ICON)
67    set (PRODUCT_ICON "${CMAKE_SOURCE_DIR}/icons/windows-icons/${PRODUCT_NAME}.ico")
68  endif ()
69
70  if (NOT PRODUCT_VERSION_MAJOR)
71    if (PROJECT_VERSION_MAJOR)
72      set (PRODUCT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
73    else ()
74      set (PRODUCT_VERSION_MAJOR 1)
75    endif ()
76  else ()
77    if (NOT ${PRODUCT_VERSION_MAJOR} MATCHES "^[0-9]+$")
78      message (FATAL_ERROR "Numeric major version number required")
79    endif ()
80  endif ()
81
82  if (NOT PRODUCT_VERSION_MINOR)
83    if (PROJECT_VERSION_MINOR)
84      set (PRODUCT_VERSION_MINOR ${PROJECT_VERSION_MINOR})
85    else ()
86      set (PRODUCT_VERSION_MINOR 0)
87    endif ()
88  else ()
89    if (NOT ${PRODUCT_VERSION_MINOR} MATCHES "^[0-9]+$")
90      message (FATAL_ERROR "Numeric minor version number required")
91    endif ()
92  endif()
93
94  if (NOT PRODUCT_VERSION_PATCH)
95    if (PROJECT_VERSION_PATCH)
96      set (PRODUCT_VERSION_PATCH ${PROJECT_VERSION_PATCH})
97    else ()
98      set (PRODUCT_VERSION_PATCH 0)
99    endif ()
100  else ()
101    if (NOT ${PRODUCT_VERSION_PATCH} MATCHES "^[0-9]+$")
102      message (FATAL_ERROR "Numeric patch version number required")
103    endif ()
104  endif()
105
106  if (NOT PRODUCT_VERSION_TWEAK)
107    if (PROJECT_VERSION_TWEAK)
108      set (PRODUCT_VERSION_TWEAK ${PROJECT_VERSION_TWEAK})
109    else ()
110      set (PRODUCT_VERSION_TWEAK 0)
111    endif ()
112  else()
113    if (NOT ${PRODUCT_VERSION_TWEAK} MATCHES "^[0-9]+$")
114      message (FATAL_ERROR "Numeric tweak version number required")
115    endif()
116  endif()
117
118  if (NOT PROJECT_VERSION_REVISION AND BUILD_TYPE_REVISION)
119    set (PRODUCT_VERSION_REVISION ${BUILD_TYPE_REVISION})
120  endif ()
121
122  if (NOT PRODUCT_VENDOR_NAME AND PROJECT_VENDOR)
123    set (PRODUCT_VENDOR_NAME ${PROJECT_VENDOR})
124  endif ()
125
126  if (NOT PRODUCT_LEGAL_COPYRIGHT)
127    if (PROJECT_COPYRIGHT)
128      set (PRODUCT_LEGAL_COPYRIGHT ${PROJECT_COPYRIGHT})
129    else ()
130      string(TIMESTAMP PRODUCT_CURRENT_YEAR "%Y")
131      set(PRODUCT_LEGAL_COPYRIGHT "${PRODUCT_VENDOR_NAME} (C) Copyright ${PRODUCT_CURRENT_YEAR}")
132    endif ()
133  endif()
134
135  if (NOT PRODUCT_COMMENTS)
136    if (PROJECT_DESCRIPTION)
137      set(PRODUCT_COMMENTS ${PROJECT_DESCRIPTION})
138    else ()
139      set(PRODUCT_COMMENTS "${PRODUCT_NAME} v${PRODUCT_VERSION_MAJOR}.${PRODUCT_VERSION_MINOR}.${PRODUCT_VERSION_PATCH}")
140    endif ()
141  endif()
142
143  if (NOT PRODUCT_ORIGINAL_FILENAME)
144    set(PRODUCT_ORIGINAL_FILENAME "${PRODUCT_NAME}")
145  endif()
146
147  if (NOT PRODUCT_INTERNAL_NAME)
148    set(PRODUCT_INTERNAL_NAME "${PRODUCT_NAME}")
149  endif()
150
151  if (NOT PRODUCT_FILE_DESCRIPTION)
152    set(PRODUCT_FILE_DESCRIPTION "${PRODUCT_COMMENTS}")
153  endif()
154
155  set (_VersionInfoFile VersionInfo_${PRODUCT_NAME}.h)
156  set (_VersionResourceFile VersionResource_${PRODUCT_NAME}.rc)
157  configure_file(
158    ${_THIS_MODULE_BASE_DIR}/VersionInfo.h.in
159    ${_VersionInfoFile}
160    @ONLY)
161  configure_file(
162    ${_THIS_MODULE_BASE_DIR}/VersionResource.rc.in
163    ${_VersionResourceFile}
164    @ONLY)
165  list(APPEND ${outfiles} ${CMAKE_CURRENT_BINARY_DIR}/${_VersionInfoFile} ${CMAKE_CURRENT_BINARY_DIR}/${_VersionResourceFile})
166  set (${outfiles} ${${outfiles}} PARENT_SCOPE)
167endfunction()
168