Commit 03b89614 authored by jcfr's avatar jcfr

COMP: Add ITKFactoryRegistration library centralizing ITK IO factory registration

This commit will ensure that ITK IO factory are properly registered on all
supported platforms.

When ITKv4 is build shared, the library holding the factory registration code
are build statically. As a consequence, when CLI module are loaded as library
the factory are registered multiple times. Around 800 factories where registered
and this was leading to poor performance when loading images.

This commit enable the building of a shared library named ITKFactoryRegistration
that should be linked against to ensure loading of the factory. This approach
can succeed thanks to the help of the ITK variable ITK_NO_IO_FACTORY_REGISTER_MANAGER.

This variable allow to disable the automatic registration of factory in selected part
of the code.

The following two cases are handled:
 - Registration of the factories within the Slicer executable.
 - Registration of the factories within CLI executable.

Fixes #2813

From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>

git-svn-id: http://svn.slicer.org/Slicer4/trunk@21592 3bd1e089-480b-0410-8dfb-8563597acbee
parent f2ccfa63
...@@ -74,6 +74,7 @@ set(SlicerApp_INCLUDE_DIRECTORIES ...@@ -74,6 +74,7 @@ set(SlicerApp_INCLUDE_DIRECTORIES
${qMRMLWidgets_INCLUDE_DIRS} ${qMRMLWidgets_INCLUDE_DIRS}
${qSlicerModulesCore_SOURCE_DIR} ${qSlicerModulesCore_SOURCE_DIR}
${qSlicerModulesCore_BINARY_DIR} ${qSlicerModulesCore_BINARY_DIR}
${ITKFactoryRegistration_INCLUDE_DIRS}
) )
include_directories(${SlicerApp_INCLUDE_DIRECTORIES}) include_directories(${SlicerApp_INCLUDE_DIRECTORIES})
......
...@@ -50,6 +50,11 @@ ...@@ -50,6 +50,11 @@
#include "qSlicerModuleManager.h" #include "qSlicerModuleManager.h"
#include "qSlicerStyle.h" #include "qSlicerStyle.h"
// ITK includes
#if ITK_VERSION_MAJOR > 3
# include "itkFactoryRegistration.h"
#endif
// VTK includes // VTK includes
//#include <vtkObject.h> //#include <vtkObject.h>
...@@ -87,6 +92,10 @@ void splashMessage(QScopedPointer<QSplashScreen>& splashScreen, const QString& m ...@@ -87,6 +92,10 @@ void splashMessage(QScopedPointer<QSplashScreen>& splashScreen, const QString& m
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int SlicerAppMain(int argc, char* argv[]) int SlicerAppMain(int argc, char* argv[])
{ {
#if ITK_VERSION_MAJOR > 3
itk::itkFactoryRegistration();
#endif
QCoreApplication::setApplicationName("Slicer"); QCoreApplication::setApplicationName("Slicer");
QCoreApplication::setApplicationVersion(Slicer_VERSION_FULL); QCoreApplication::setApplicationVersion(Slicer_VERSION_FULL);
//vtkObject::SetGlobalWarningDisplay(false); //vtkObject::SetGlobalWarningDisplay(false);
......
...@@ -24,6 +24,20 @@ set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES ...@@ -24,6 +24,20 @@ set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES
${SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES} ${Slicer_BaseCLI_INCLUDE_DIRS} ${SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES} ${Slicer_BaseCLI_INCLUDE_DIRS}
CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE
) )
if(${ITK_VERSION_MAJOR} GREATER 3)
set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES
${SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES} ${ITKFactoryRegistration_INCLUDE_DIRS}
CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE
)
set(SlicerExecutionModel_CLI_LIBRARY_WRAPPER_CXX
${CMAKE_CURRENT_BINARY_DIR}/SEMCommandLineLibraryWrapper.cxx
CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE
)
configure_file(
SEMCommandLineLibraryWrapper.cxx.in
${SlicerExecutionModel_CLI_LIBRARY_WRAPPER_CXX}
)
endif()
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Update Slicer_Base_INCLUDE_DIRS # Update Slicer_Base_INCLUDE_DIRS
......
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $HeadURL$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
// This file is intended to be compiled and linked against a shared
// library CLP to prevent the need to compile twice.
#ifdef WIN32
#define MODULE_IMPORT __declspec(dllimport)
#else
#define MODULE_IMPORT
#endif
#define ITK_VERSION_MAJOR @ITK_VERSION_MAJOR@
#if ITK_VERSION_MAJOR >= 4
# include "itkFactoryRegistration.h"
#endif
extern "C" MODULE_IMPORT int ModuleEntryPoint(int, char* []);
int main(int argc, char** argv)
{
#if ITK_VERSION_MAJOR >= 4
itk::itkFactoryRegistration();
#endif
return ModuleEntryPoint(argc, argv);
}
...@@ -278,8 +278,9 @@ slicer_config_set_ep( ...@@ -278,8 +278,9 @@ slicer_config_set_ep(
"@SLICERLIBCURL_DIR_CONFIG@" "@SLICERLIBCURL_DIR_CONFIG@"
CACHE PATH "Path to Curl build or install directory" FORCE) CACHE PATH "Path to Curl build or install directory" FORCE)
# SlicerExecutionModel extra include directories # SlicerExecutionModel settings
set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES "@SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES_CONFIG@") set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES "@SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES_CONFIG@")
set(SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES "@SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES_CONFIG@")
slicer_config_set_ep( slicer_config_set_ep(
SlicerExecutionModel_DIR SlicerExecutionModel_DIR
......
...@@ -114,6 +114,7 @@ endif() ...@@ -114,6 +114,7 @@ endif()
if(Slicer_BUILD_CLI_SUPPORT) if(Slicer_BUILD_CLI_SUPPORT)
set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES_CONFIG ${SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES}) set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES_CONFIG ${SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES})
set(SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES_CONFIG ${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES})
endif() endif()
# Export Targets file. # Export Targets file.
......
...@@ -128,6 +128,11 @@ endif() ...@@ -128,6 +128,11 @@ endif()
# Prerequisites # Prerequisites
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
# By default, the "<PROJECT>_USE_FILE" of each slicer external project will be included. # By default, the "<PROJECT>_USE_FILE" of each slicer external project will be included.
# This can be changed by setting the variable Slicer_SKIP_EXTERNAL_PROJECTS_USEFILE to TRUE # This can be changed by setting the variable Slicer_SKIP_EXTERNAL_PROJECTS_USEFILE to TRUE
if(NOT DEFINED Slicer_SKIP_EXTERNAL_PROJECTS_USEFILE) if(NOT DEFINED Slicer_SKIP_EXTERNAL_PROJECTS_USEFILE)
......
...@@ -605,6 +605,10 @@ if(${ITK_VERSION_MAJOR} VERSION_LESS ${expected_ITK_VERSION_MAJOR}) ...@@ -605,6 +605,10 @@ if(${ITK_VERSION_MAJOR} VERSION_LESS ${expected_ITK_VERSION_MAJOR})
" ${ITK_CONFIG}, version: ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}\n") " ${ITK_CONFIG}, version: ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}\n")
endif() endif()
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
...@@ -753,6 +757,7 @@ endif() ...@@ -753,6 +757,7 @@ endif()
# SlicerExecutionModel settings # SlicerExecutionModel settings
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES "" CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE) set(SlicerExecutionModel_EXTRA_INCLUDE_DIRECTORIES "" CACHE INTERNAL "SlicerExecutionModel extra includes" FORCE)
set(SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES "" CACHE INTERNAL "SlicerExecutionModel extra executable target libraries" FORCE)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Set Slicer buildin libraries *_DIR variables # Set Slicer buildin libraries *_DIR variables
......
...@@ -12,7 +12,19 @@ set(GENERATECLP_USE_MD5 ON) ...@@ -12,7 +12,19 @@ set(GENERATECLP_USE_MD5 ON)
# Order of project directory matters. Project should be topologically ordered # Order of project directory matters. Project should be topologically ordered
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
set(dirs set(dirs )
if(${ITK_VERSION_MAJOR} GREATER 3)
list(APPEND dirs
ITKFactoryRegistration
)
set(SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES
${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES} ITKFactoryRegistration
CACHE INTERNAL "SlicerExecutionModel extra executable target libraries" FORCE
)
endif()
list(APPEND dirs
vtkTeem vtkTeem
vtkITK vtkITK
FreeSurfer FreeSurfer
......
...@@ -15,6 +15,10 @@ endif() ...@@ -15,6 +15,10 @@ endif()
#include(${KWWidgets_USE_FILE}) #include(${KWWidgets_USE_FILE})
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
if(NOT DEFINED BUILD_SHARED_LIBS) if(NOT DEFINED BUILD_SHARED_LIBS)
......
project(ITKFactoryRegistration)
cmake_minimum_required(VERSION 2.8.4)
find_package(ITK REQUIRED)
# This is the Slicer library in charge of registering the default ITK factories.
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 0)
include(${ITK_USE_FILE})
# --------------------------------------------------------------------------
# Include dirs
# --------------------------------------------------------------------------
set(include_dirs
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
include_directories(${include_dirs})
# --------------------------------------------------------------------------
# Configure headers
# --------------------------------------------------------------------------
set(configure_header_file itkFactoryRegistrationConfigure.h)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/${configure_header_file}.in
${CMAKE_CURRENT_BINARY_DIR}/${configure_header_file}
)
# --------------------------------------------------------------------------
# Install headers
# --------------------------------------------------------------------------
if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT)
set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON)
endif()
if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT)
file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.(h|txx)")
install(
FILES ${headers} ${CMAKE_CURRENT_BINARY_DIR}/${configure_header_file}
DESTINATION include/${PROJECT_NAME} COMPONENT Development)
endif()
# --------------------------------------------------------------------------
# Sources
# --------------------------------------------------------------------------
set(srcs
itkFactoryRegistration.cxx
)
# --------------------------------------------------------------------------
# Build library
# --------------------------------------------------------------------------
set(lib_name ${PROJECT_NAME})
add_library(${lib_name} SHARED ${srcs})
set(libs
${ITK_LIBRARIES}
)
target_link_libraries(${lib_name} ${libs})
# Apply user-defined properties to the library target.
if(Slicer_LIBRARY_PROPERTIES)
set_target_properties(${lib_name} PROPERTIES ${Slicer_LIBRARY_PROPERTIES})
endif()
# --------------------------------------------------------------------------
# Export target
# --------------------------------------------------------------------------
if(NOT DEFINED ${PROJECT_NAME}_EXPORT_FILE)
set(${PROJECT_NAME}_EXPORT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake)
endif()
export(TARGETS ${lib_name} APPEND FILE ${${PROJECT_NAME}_EXPORT_FILE})
# --------------------------------------------------------------------------
# Install library
# --------------------------------------------------------------------------
if(NOT DEFINED ${PROJECT_NAME}_INSTALL_BIN_DIR)
set(${PROJECT_NAME}_INSTALL_BIN_DIR bin)
endif()
if(NOT DEFINED ${PROJECT_NAME}_INSTALL_LIB_DIR)
set(${PROJECT_NAME}_INSTALL_LIB_DIR lib/${PROJECT_NAME})
endif()
install(TARGETS ${lib_name}
RUNTIME DESTINATION ${${PROJECT_NAME}_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
LIBRARY DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT Development
)
# --------------------------------------------------------------------------
# Set INCLUDE_DIRS variable
# --------------------------------------------------------------------------
set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
CACHE INTERNAL "${PROJECT_NAME} include dirs" FORCE)
#include "itkFactoryRegistration.h"
// ITK includes
#include <itkImageFileReader.h>
#include <itkTransformFileReader.h>
// The following code is required to ensure that the
// mechanism allowing the ITK factory to be registered is not
// optimized out by the compiler.
void itk::itkFactoryRegistration(void)
{
return;
}
#ifndef __itkFactoryRegistration_h
#define __itkFactoryRegistration_h
#include "itkFactoryRegistrationConfigure.h"
namespace itk {
ITKFactoryRegistration_EXPORT void itkFactoryRegistration(void);
}
#endif
#ifndef __itkFactoryRegistrationConfigure_h
#define __itkFactoryRegistrationConfigure_h
#if defined(WIN32) && !defined(ITKFactoryRegistration_STATIC)
# if defined(ITKFactoryRegistration_EXPORTS)
# define ITKFactoryRegistration_EXPORT __declspec( dllexport )
# else
# define ITKFactoryRegistration_EXPORT __declspec( dllimport )
# endif
#else
# define ITKFactoryRegistration_EXPORT
#endif
#endif
...@@ -12,6 +12,10 @@ if(POLICY CMP0017) ...@@ -12,6 +12,10 @@ if(POLICY CMP0017)
endif() endif()
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
if(NOT DEFINED BUILD_SHARED_LIBS) if(NOT DEFINED BUILD_SHARED_LIBS)
......
...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED) ...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED)
include(${VTK_USE_FILE}) include(${VTK_USE_FILE})
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
option(MRML_USE_Teem "Build MRML with Teem support." ON) option(MRML_USE_Teem "Build MRML with Teem support." ON)
......
...@@ -12,6 +12,10 @@ if(POLICY CMP0017) ...@@ -12,6 +12,10 @@ if(POLICY CMP0017)
endif() endif()
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
find_package(VTK REQUIRED) find_package(VTK REQUIRED)
......
...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED) ...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED)
include(${VTK_USE_FILE}) include(${VTK_USE_FILE})
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
find_package(SLICERLIBCURL REQUIRED) find_package(SLICERLIBCURL REQUIRED)
......
...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED) ...@@ -15,6 +15,10 @@ find_package(VTK REQUIRED)
include(${VTK_USE_FILE}) include(${VTK_USE_FILE})
find_package(ITK REQUIRED) find_package(ITK REQUIRED)
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
if(NOT DEFINED BUILD_SHARED_LIBS) if(NOT DEFINED BUILD_SHARED_LIBS)
......
...@@ -7,6 +7,10 @@ endif(VTK_FOUND) ...@@ -7,6 +7,10 @@ endif(VTK_FOUND)
find_package( ITK ) find_package( ITK )
if( ITK_FOUND ) if( ITK_FOUND )
if(${ITK_VERSION_MAJOR} GREATER 3)
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) # See Libs/ITKFactoryRegistration/CMakeLists.txt
list(APPEND ITK_LIBRARIES ITKFactoryRegistration)
endif()
include(${ITK_USE_FILE}) include(${ITK_USE_FILE})
else( ITK_FOUND ) else( ITK_FOUND )
message( FATAL_ERROR "Cannot build without ITK" ) message( FATAL_ERROR "Cannot build without ITK" )
......
...@@ -36,7 +36,7 @@ if(NOT DEFINED SlicerExecutionModel_DIR) ...@@ -36,7 +36,7 @@ if(NOT DEFINED SlicerExecutionModel_DIR)
ExternalProject_Add(${proj} ExternalProject_Add(${proj}
GIT_REPOSITORY "${git_protocol}://github.com/Slicer/SlicerExecutionModel.git" GIT_REPOSITORY "${git_protocol}://github.com/Slicer/SlicerExecutionModel.git"
GIT_TAG "d3f1363509cd977a628714bdd178feaafef5f91e" GIT_TAG "2986286df7819b4bd2c0b7e2d25efe7fd23ff51f"
"${slicer_external_update}" "${slicer_external_update}"
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
BINARY_DIR ${proj}-build BINARY_DIR ${proj}-build
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment