[CMake] How to define custom import library name (MSVC)?

Michael Hertling mhertling at online.de
Mon Oct 17 10:09:37 EDT 2011


On 10/17/2011 01:58 PM, Michael Hertling wrote:
> On 10/16/2011 06:27 PM, zex spectrum wrote:
>> Hello,
>>
>> I generate a shared library named, for example, mylib80.dll (it has
>> postfix "80", because I want to embed version info into library name.
>> I use set_target_properties with <Config>_POSTFIX property to achieve
>> this. By default, CMake names corresponding import library as
>> mylib80.lib. But I want my shared lib to have an import lib named
>> mylib.lib (without version embedded into its name). Is it possible at
>> all? I tried IMPORT_SUFFIX, but it seems to not work as I expect.
> 
> AFAIK, a shared library target's import library is named like
> 
> ... + ARCHIVE_OUTPUT_NAME_<CONFIG> + <CONFIG>_POSTFIX + IMPORT_SUFFIX
> 
> so you cannot use the IMPORT_SUFFIX to overwrite the <CONFIG>_POSTFIX.
> 
>> I use MSVC, I do not need to have this for GCC and other compilers.
>>
>> Any help would be appreciated.
> 
> You might use an additional INSTALL(CODE ...) step, see the attached
> CMakeLists.txt file. Note that the LOCATION property might have side
> effects, cf. [1], so it's probably best to place it at the very end.
> 
> 'hope that helps.
> 
> Regards,
> 
> Michael
> 
> [1] http://public.kitware.com/Bug/view.php?id=11671

Addendum: If you want to be independent of the import library's actual
suffix, you might use INSTALL(SCRIPT ...) instead of INSTALL(CODE ...)
with the import library installed temporarily under CMAKE_BINARY_DIR:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(IMPLIB C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(SRCDIR "${CMAKE_BINARY_DIR}/fimplib")
SET(DSTDIR "${CMAKE_INSTALL_PREFIX}/lib")
CONFIGURE_FILE(
    "${CMAKE_SOURCE_DIR}/install_implib.cmake.in"
    "${CMAKE_BINARY_DIR}/install_implib.cmake"
    @ONLY)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c
"__declspec(dllexport) void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
SET_TARGET_PROPERTIES(f PROPERTIES
    DEBUG_POSTFIX "80"
    IMPORT_SUFFIX ".imp")  # <-- for demonstration.
INSTALL(TARGETS f
    RUNTIME DESTINATION bin
    ARCHIVE DESTINATION ${CMAKE_BINARY_DIR}/fimplib)
INSTALL(SCRIPT "${CMAKE_BINARY_DIR}/install_implib.cmake")

# install_implib.cmake.in:
FILE(GLOB F "@SRCDIR@/*")
GET_FILENAME_COMPONENT(F_EXT "${F}" EXT)
GET_FILENAME_COMPONENT(F_NWE "${F}" NAME_WE)
STRING(REGEX REPLACE "80\$" "" F_NWE "${F_NWE}")
FILE(RENAME "${F}" "@SRCDIR@/${F_NWE}${F_EXT}")
FILE(INSTALL "@SRCDIR@/${F_NWE}${F_EXT}"
    DESTINATION "@DSTDIR@"
    USE_SOURCE_PERMISSIONS)

AFAICS, the intermediate installation of the import library is necessary
to separate the latter from the DLL part, so one has a chance to rename
it without knowing its actual suffix. Moreover, the FILE(INSTALL ...)
is told to retain its permissions which INSTALL(FILES ...) wouldn't.

The basic idea is: The import library should be installed once with
INSTALL(... ARCHIVE DESTINATION ...) to get the correct permissions,
and you can not modify its name separately from the DLL part before
the INSTALL() command. So, you need to rename it afterwards, either
in the installation directory with knowledge of its suffix, or in a
dedicated intermediate directory where you can use FILE(GLOB ...)
and GET_FILENAME_COMPONENT() without knowing the suffix.

Regards,

Michael


More information about the CMake mailing list