IMPORTED_LOCATION_<CONFIG> problem with configuration mappings
Normally, when using the target properties IMPORTED_LOCATION and (say) IMPORTED_LOCATION_DEBUG, that's interpreted as "use the debug-specific location for the debug configuration, and the unspecific IMPORTED_LOCATION for all other configurations" and some of the libraries we use depend upon that behaviour.
Now, when using custom configuration mapping, this breaks down. Say our project defines custom configurations Deb and Rel together with mappings to standard configurations external libraries are like to use:
set(CMAKE_CONFIGURATION_TYPES "Deb;Rel")
set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS "Deb")
# Omitted: Set compiler and linker flag variables...
[...]
set(CMAKE_MAP_IMPORTED_CONFIG_DEB "Debug")
set(CMAKE_MAP_IMPORTED_CONFIG_REL "Release")
Define imported library that doesn't know our configurations...
add_library(mylib STATIC IMPORTED)
set_target_properties(mylib PROPERTIES
IMPORTED_CONFIGURATIONS "Debug;Release"
IMPORTED_LOCATION "/foo/bar/baz_release.a"
IMPORTED_LOCATION_DEBUG "/foo/bar/baz_debug.a")
...and link it to some executable:
add_executable(myapp main.c)
target_link_libraries(myapp mylib)
What happens now is that the debug configuration "Deb" works fine, but in the release configuration "Rel" mylib is not found. I tested this with CMake 3.6.1 and the Visual Studio 2013, 2015, and Ninja generators.
The mapping only works with configuration-specific location properties. Setting the target property
IMPORTED_LOCATION_RELEASE "/foo/bar/baz_release.a"
for mylib makes it work. CMake seems to only take the IMPORTED_LOCATION_ variables into account when mapping configurations. I could work around this by setting those properties explicitly for imported libraries, but I'd much rather have CMake behave the same way as when linking; perhaps by checking IMPORTED_CONFIGURATIONS for existance of a particular configuration C and then use IMPORTED_LOCATION_C or IMPORTED_LOCATION as a fallback.
The full test case (with an empty main.c). This should (in "Rel" configuration, and in my book) try to link against /foo/bar/baz_release.a, not mylib-NOTFOUND. Uncommenting the line marked # A makes it work.
cmake_minimum_required(VERSION 3.0)
project(foobar C)
set(CMAKE_CONFIGURATION_TYPES "Deb;Rel")
set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS "Deb")
set(CMAKE_C_FLAGS_DEB "${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_EXE_LINKER_FLAGS_DEB "${CMAKE_C_LINKER_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_REL "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_REL "${CMAKE_C_LINKER_FLAGS_RELEASE}")
set(CMAKE_MAP_IMPORTED_CONFIG_DEB "Debug")
set(CMAKE_MAP_IMPORTED_CONFIG_REL "Release")
add_library(mylib STATIC IMPORTED)
set_target_properties(mylib PROPERTIES
IMPORTED_CONFIGURATIONS "Debug;Release"
IMPORTED_LOCATION "/foo/bar/baz_release.a"
IMPORTED_LOCATION_DEBUG "/foo/bar/baz_debug.a"
#IMPORTED_LOCATION_RELEASE "/foo/bar/baz_release.a" # A
)
add_executable(myapp main.c)
target_link_libraries(myapp mylib)