ITK
ITK copied to clipboard
When installing two configurations of ITK on the same install folder, the ITKTarget*.cmake file of the first install is removed
Hi,
I want to create an installation of ITK with the debug and releaseWithDebInfo dll on the same folder, thanks to the CMAKE_DEBUG_POSTFIX. For this, I run two times the build and installation with the releaseWithDebInfo and debug build type, and the same install prefix folder. However, I can notice in the second install, the following line:
-- Old export file "D:/.conan/8c8045/1/lib/cmake/ITK-5.0/ITKTargets.cmake" will be replaced. Removing files [D:/.conan/8c8045/1/lib/cmake/ITK-5.0/ITKTargets-relwithdebinfo.cmake].
-- Installing: D:/.conan/8c8045/1/lib/cmake/ITK-5.0/ITKTargets.cmake
-- Installing: D:/.conan/8c8045/1/lib/cmake/ITK-5.0/ITKTargets-debug.cmake
This is the first time I see an install script uninstalling cmake target files from a previous install. Is it normal or is it a bug ? If it is normal, how I am supposed to achieve an same installation for two configurations? Shall I merge myself the two installs and not use the same install prefix ?
I am building ITK 5.0.1, with cmake 3.16.5, on MSVC 16.5, Windows 10. Here is my cmake configuration: BUILD_SHARED_LIBS=ON CMAKE_DEBUG_POSTFIX="d" BUILD_TESTING]=OFF Module_RTK=ON RTK_USE_CUDA=ON RTK_BUILD_APPLICATIONS=OFF
Best regards, Simon
If you install multiple configurations, there should be multiple ITKTargets-*.cmake
files, one for each configuration. But ITKTargets.cmake
exists for each configuration, and needs to be overwritten. Are file contents the same? Does your installation work with both configurations?
Please use a separate install prefix per configuration.
@dzenanz : The ITKTargets.cmake targets file are exactly the same for both Debug and RelWithDebInfo config. Yes my installation works with both configuration.
@thewtex : Do you know why we have that behavior? I am genuinely curious. We use the same config mixing mechanism for our own libraries, with VTK 8.2.0 it is also ok, and I feel that it was the intended behavior of cmake as we have those target files split into the common part and the part different for each config.
I don't think it is possible to avoid overwriting ITKTargets.cmake
. And if everything works fine, that warning is not much of an issue.
@Siron777 patches are welcome to improve support for this if you want to dive into the CMake export configuration and any necessary changes to the third party library configurations that we vendor.
@dzenanz ITKTargets.cmake is indeed fine, it is recreated exactly the same (I though your question of comparison was to be sure this file was the same for both configuration and could be mix up), the issue is about ITKTargets-RelWithDebInfo.cmake which is removed by the debug install (this is specified at the end of the warning) and not recreated. At the end the install folder has the RelWithDebInfo dll/lib, but not any more the ITKTargets-RelWithDebInfo.cmake.
@thewtex If I can, I will help. What the CMake install is doing here does not seems to be the usual case. In our internal projects, or in VTK, I do not observer that behavior. I do not know what is triggering that behavior.
From experience with VCPKG: ITKTargets.cmake might not be the same if libraries are linked directly and the configuration have different prefixes. Then the INTERFACE_LINK_LIBRARIES
will contain the library name and the absoulte path to the library. This is a typical problem with *Targets.cmake
in VCPKG and results in a lot of link errors since it also merges artifacts from Debug and Release. If ITK switched like VTK to be all targets in the INTERFACE_LINK_LIBRARIES
property of the exported targets then it should be fine.
This issue has been automatically marked as stale because it has not had recent activity. Thank you for your contributions.
Please use a separate install prefix per configuration.
I know this is a three year old conversation, however I disagree with this. There are multiple libraries that are capable of handling how the install configurations are handled.
Example 1: Boost uses libName-generatorName-generatorConfig-gd-x64-version.lib for a debug name while: libName-generatorName-generatorConfig-x64-version.lib for a release mode.
The Targets file knows how to differentiate each build configuration and links to them accordingly.
I propose one of the two following changes to your CMake files when it comes to installation. Let's pick Common for this example.
Right after itk_module_add_library
, you can do:
set_target_properties(ITKCommon PROPERTIES DEBUG_POSTFIX "d")
This will populate in the installation lib folder: ITKCommon-versiond.lib
And if someone is configuring a Release build it will place in the lib folder: ITKCommon-version.lib Meaning both a debug and release version can live happily side by side in the same folder. This is the most cross-compatible friendly version of doing it. Since it only adds a d to the library name.
The other proposal, which may be the easiest and less labor intensive, would be to edit the ITKModuleMacros.cmake file starting at line 421 change:
install(TARGETS ${_name}
EXPORT ${${itk-module}-targets}
RUNTIME DESTINATION ${${itk-module}_INSTALL_RUNTIME_DIR} COMPONENT ${runtime_component}
LIBRARY DESTINATION ${${itk-module}_INSTALL_LIBRARY_DIR} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${${itk-module}_INSTALL_ARCHIVE_DIR} COMPONENT Development
)
to:
install(TARGETS ${_name}
EXPORT ${${itk-module}-targets}
RUNTIME DESTINATION ${${itk-module}_INSTALL_RUNTIME_DIR}/$<CONFIG> COMPONENT ${runtime_component}
LIBRARY DESTINATION ${${itk-module}_INSTALL_LIBRARY_DIR}/$<CONFIG> COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${${itk-module}_INSTALL_ARCHIVE_DIR}/$<CONFIG> COMPONENT Development
)
(Thinking about it, you might be able to add the suffix somewhere in this file as well) This will separate the libraries for you in different configuration folders. Which will look something like:
InstallRoot
-- bin
-- Debug
-- Release
-- ...
-- include
-- lib
-- cmake
-- gdcmopenjpeg-2.3
-- pkgconfig
-- Debug
-- Release
-- ...
-- share
However, this isn't the most cross-compatible friendly because not all generators use configurations by default. I'm not sure if ITK sets a default configuration at the beginning or not. For example in Ubuntu running the following:
cmake -DCMAKE_INSTALL_PREFIX=<PATH> ../
Will populate the $<CONFIG>
property as ''
. Which does nothing since ''
is an empty folder but it doesn't look good when the generation is being run. Instead the user would need to do:
cmake -DCMAKE_INSTALL_PREFIX=<PATH> -DCMAKE_BUILD_TYPE=<CONFIG> ../
CMAKE_BUILD_TYPE can be set in the top level CMakeLists.txt file if this approach is preferred.
The reason I disagree with using a separate install prefix per configuration is because the headers files will get installed in each prefix configuration. If a user is using Visual Studio with the four possible configurations that is four copies of header files that will installed which is unnecessary. Not to mention this puts the responsibility on the user to put in their own CMake files something like (this isn't correct CMake Syntax btw)
if($<CONFIG> == Debug)
set(ITK_ROOT_DIR <Install Path>/Debug)
elseif($<CONFIG> == Release)
set(ITK_ROOT_DIR <Install Path>/Release)
elseif($<CONFIG> == ...)
set(ITK_ROOT_DIR <Install Path>/...)
endif()
find_package(ITK)
This is super tedious and instead the user should be able to do set(ITK_ROOT_DIR <Install Path>)
The targets file is supposed to be responsible for handling the multiple configurations of installation. However, when the library names do not change or their physical location, they will get overwritten each time a new install configuration is made. The User should be able to link to ITK without having to manage the configurations manually. That is the point of CMake.
Apparently this is working correctly in case of CMAKE_DEBUG_POSTFIX="d": ITKTargets.cmake include ALL ITKTargets-*.cmake in the same folder. The only problem here is that you should be aware of CMAKE_DEBUG_POSTFIX="d" otherwise you'll overwrite lib files
If setting CMAKE_DEBUG_POSTFIX
to d
is all it takes, could you make that a PR?