How to Generate Windows DLL versioning information

2019-01-31 13:33发布

问题:

I'm using CMake to build a shared library, however for the Windows DLL I need the versioning information, like:

  • FileDescription
  • FileVersion
  • InternalName
  • LegalCopyright
  • OriginalFilename
  • ProductName
  • ProductVersion

So far, all I have are the VERSION and SOVERSION properties, but these don't seem to correlate to the FileVersion information I was expecting.

set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES} )

SET_TARGET_PROPERTIES(${LIC_TARGET}
    PROPERTIES
    VERSION ${MY_PRODUCT_NUMBER}.${MY_PRODUCT_VERSION}.${MY_BUILD_NUMBER}
    SOVERSION ${MY_PRODUCT_NUMBER})

I've found manual methods (see example at the bottom) but would prefer to contain this within CMake.

Help?

回答1:

You could use your CMake variable values in conjunction with a version.rc.in file and the configure_file command.

// version.rc.in
#define VER_FILEVERSION             @MY_PRODUCT_NUMBER@,@MY_PRODUCT_VERSION@,@MY_BUILD_NUMBER@,0
#define VER_FILEVERSION_STR         "@MY_PRODUCT_NUMBER@.@MY_PRODUCT_VERSION@.@MY_BUILD_NUMBER@.0\0"

#define VER_PRODUCTVERSION          @MY_PRODUCT_NUMBER@,@MY_PRODUCT_VERSION@,@MY_BUILD_NUMBER@,0
#define VER_PRODUCTVERSION_STR      "@MY_PRODUCT_NUMBER@.@MY_PRODUCT_VERSION@.@MY_BUILD_NUMBER@\0"
//
// ...along with the rest of the file from your "manual methods" reference

And then, in your CMakeLists.txt file:

# CMakeLists.txt
set(MY_PRODUCT_NUMBER 3)
set(MY_PRODUCT_VERSION 5)
set(MY_BUILD_NUMBER 49)

configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in
  ${CMAKE_CURRENT_BINARY_DIR}/version.rc
  @ONLY)

set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES}
  ${CMAKE_CURRENT_BINARY_DIR}/version.rc)

# Alternatively you could simply include version.rc in another rc file
# if there already is one in one of the files in ${SOURCES}


回答2:

I'm had same problem and have automated version generation for my projects. You need three files from github:

  • generate_product_version.cmake
  • VersionInfo.in
  • VersionResource.rc

Put it in cmake subdirectory of your project and make sure to include it to CMAKE_MODULE_PATH like:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)

Then before add_executable() or add_library(SHARED) your target, use:

include(generate_product_version)
generate_product_version(
   VersionFilesOutputVariable
   NAME "My Great Project"
   ICON ${PATH_TO_APPLICATION_ICON}
   VERSION_MAJOR 1
   VERSION_MINOR 3
   VERSION_PATCH ${BUILD_COUNTER}
   VERSION_REVISION ${BUILD_REVISION}
)

Full list of supported resource strings see in generate_product_version.cmake.

VersionInfo.h and VersionResource.rc will be generated to cmake binaries folder. Variable VersionFilesOutputVariable will hold paths to these files. Just add this list to your target:

add_executable(MyGreatProject ${your-target-sources} ${VersionFilesOutputVariable})

UPDATE: Corrected generate_product_version script parameters from VERSION_PATH to VERSION_PATCH.



回答3:

There is an even easier way than the accepted answer. It does not involve transforming an input resource.rc.in. Simply create a generic version.rc file as described here and then from your CMakeLists.txt do this:

#CMakeLists.txt

add_definitions(-DVER_COMPANYNAME_STR="MyCompany")
add_definitions(-DVER_FILEVERSION_STR="1,1,0.0")
# ...
# add all the other defines here

set(LIC_TARGET MySharedLib)
add_library(${LIC_TARGET} SHARED ${SOURCES} version.rc)

This has the added benefit that the defines are accessible from your source code as well, so you have programmatic access to your version.