From 97ea40c4ad99a6846a6a30fff6e136847811a579 Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Thu, 12 Feb 2026 21:52:34 +0000 Subject: [PATCH 1/4] BUG: Use correct variable for linking libraries for tests --- test/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 43d480f..6cd4334 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,10 +4,7 @@ set(TotalVariationTests itkProxTVImageFilterTest.cxx ) -set(Libraries ${TotalVariation-Test_LIBRARIES}) -list(APPEND Libraries ${_proxTV_lib}) - -CreateTestDriver(TotalVariation "${Libraries}" "${TotalVariationTests}") +CreateTestDriver(TotalVariation "${TotalVariation-Test_LIBRARIES}" "${TotalVariationTests}") itk_add_test(NAME itkProxTVImageFilterTest COMMAND TotalVariationTestDriver From 8c38aaac92e6e373c9fd82b033374afbc9c0bd64 Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Thu, 12 Feb 2026 21:53:42 +0000 Subject: [PATCH 2/4] BUG: Address issues related to ITK update to modern interfaces Recent changes to ITK have been made to use CMake interfaces over raw libraries and files, along with adding the ITK namespace to targets: See InsightSoftwareConsortium/ITK#5721 Refactored installation of proxTV so that it is no longer done by the fetched project but controlled through the ITK module macros as a target. This change consistently uses the proxTV namespace for compatibility between uses of the proxTV. --- CMakeLists.txt | 142 +++++++++++++----------------------------- itk-module-init.cmake | 3 - 2 files changed, 42 insertions(+), 103 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99ab4e7..090d46e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,10 @@ -cmake_minimum_required(VERSION 3.16.2) +# 3.23 Required for proxTV FILE_SETS +cmake_minimum_required(VERSION 3.23.0) project(TotalVariation) -if(ITK_USE_SYSTEM_proxTV) - set(TotalVariation_LIBRARIES proxTV::proxTV) -else() - set(TotalVariation_LIBRARIES proxTV) -endif() -set(${PROJECT_NAME}_THIRD_PARTY 1) +set(TotalVariation_LIBRARIES proxTV::proxTV) + include(itk-module-init.cmake) @@ -16,129 +13,75 @@ if(NOT ITK_SOURCE_DIR) list(APPEND CMAKE_MODULE_PATH ${ITK_CMAKE_DIR}) endif() -include(CMakeParseArguments) include(FetchContent) -# Compile definition needed for proxTV headers -# This will propagate to wrapping. -# For wrapping to work, requires ITK with patch: -# https://github.com/InsightSoftwareConsortium/ITK/pull/707 -add_compile_definitions(NOMATLAB) - message(STATUS "TotalVariation_proxTV_USE_EIGEN: ${TotalVariation_proxTV_USE_EIGEN}") -if(TotalVariation_proxTV_USE_EIGEN) - if(NOT ITK_USE_SYSTEM_EIGEN) - # Set Eigen3_DIR to the internal Eigen3 used in ITK - set(Eigen3_DIR "${ITKInternalEigen3_DIR}") - message(STATUS "ITKTotalVariation: Using internal ITK Eigen Config found in: ${Eigen3_DIR}") - endif() - find_package(Eigen3 REQUIRED) - set(${PROJECT_NAME}_EXPORT_CODE_INSTALL -"${${PROJECT_NAME}_EXPORT_CODE_INSTALL} -find_package(OpenMP) -set(Eigen3_DIR \"${Eigen3_DIR}\") -find_package(Eigen3 REQUIRED CONFIG) -") - set(${PROJECT_NAME}_EXPORT_CODE_BUILD -"${${PROJECT_NAME}_EXPORT_CODE_BUILD} -if(NOT ITK_BINARY_DIR) - find_package(OpenMP) - set(Eigen3_DIR \"${Eigen3_DIR}\") - find_package(Eigen3 REQUIRED CONFIG) -endif() -") -else() - # proxTV will be build with external system LAPACK instead of Eigen3 - set(proxTV_USE_LAPACK 1) - add_compile_definitions(PROXTV_USE_LAPACK) -endif() -# _proxTV_lib will be `proxTV::proxTV` when find_package, and `proxTV` when add_subdirectory(proxTV_folder) -set(_proxTV_lib "") # if proxTV is built elsewhere if(ITK_USE_SYSTEM_proxTV) find_package(proxTV REQUIRED CONFIG) - set(_proxTV_lib proxTV::proxTV) - set(proxTV_DIR_INSTALL ${proxTV_DIR}) - set(proxTV_DIR_BUILD ${proxTV_DIR}) - # It is only needed to EXPORT_CODE_BUILD when using external proxTV + + # It is needed to EXPORT_CODE_BUILD when using external proxTV set(${PROJECT_NAME}_EXPORT_CODE_BUILD "${${PROJECT_NAME}_EXPORT_CODE_BUILD} if(NOT ITK_BINARY_DIR) - find_package(OpenMP) - set(proxTV_DIR \"${proxTV_DIR_BUILD}\") find_package(proxTV REQUIRED CONFIG) endif() ") + # When this module is loaded by an app, it is needed to find proxTV and OpenMP + set(${PROJECT_NAME}_EXPORT_CODE_INSTALL + "${${PROJECT_NAME}_EXPORT_CODE_INSTALL} + find_package(proxTV REQUIRED CONFIG) + ") + else() # build proxTV here with the selected Eigen3 - # Build proxTV with C++11 + # Build proxTV with C++14 if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) +# set(CMAKE_CXX_STANDARD 14) endif() if(NOT CMAKE_CXX_STANDARD_REQUIRED) - set(CMAKE_CXX_STANDARD_REQUIRED ON) +# set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() if(NOT CMAKE_CXX_EXTENSIONS) - set(CMAKE_CXX_EXTENSIONS OFF) +# set(CMAKE_CXX_EXTENSIONS OFF) endif() - set(proxTV_GIT_REPOSITORY "https://github.com/phcerdan/proxTV.git") - set(proxTV_GIT_TAG "use_eigen") + set(proxTV_Eigen_LIBRARIES ITK::ITKEigen3Module) + + set(proxTV_GIT_REPOSITORY "https://github.com/InsightSoftwareConsortium/proxTV.git") + set(proxTV_GIT_TAG "for/itk-proxtv-3.3.0-69062fe5") FetchContent_Declare( proxtv_fetch GIT_REPOSITORY ${proxTV_GIT_REPOSITORY} - GIT_TAG ${proxTV_GIT_TAG}) - FetchContent_GetProperties(proxTV_fetch) + GIT_TAG ${proxTV_GIT_TAG} + ) + # proxTV options: - set(Eigen3_DIR "${Eigen3_DIR}") # This is not needed but explicit helps reader. - set(proxTV_USE_LAPACK 0) - if(NOT DEFINED proxTV_INSTALL_INCLUDE_DIR) - if(NOT ITK_SOURCE_DIR) - set(ITK_INSTALL_INCLUDE_DIR include/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}) - endif() - set(proxTV_INSTALL_INCLUDE_DIR ${ITK_INSTALL_INCLUDE_DIR}/proxTV) - endif() - if(NOT DEFINED proxTV_INSTALL_LIB_DIR) - if(NOT ITK_SOURCE_DIR) - set(ITK_INSTALL_LIBRARY_DIR lib) - endif() - set(proxTV_INSTALL_LIB_DIR ${ITK_INSTALL_LIBRARY_DIR}) - endif() - if(NOT DEFINED proxTV_INSTALL_CMAKE_DIR) - if(NOT ITK_SOURCE_DIR) - set(ITK_INSTALL_PACKAGE_DIR "lib/cmake/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}") - endif() - set(proxTV_INSTALL_CMAKE_DIR ${ITK_INSTALL_PACKAGE_DIR}/Modules) + if(TotalVariation_proxTV_USE_EIGEN) + set(proxTV_USE_LAPACK 0) + else() + set(proxTV_USE_LAPACK 1) endif() + # end proxTV options FetchContent_MakeAvailable(proxTV_fetch) - # proxTV will generate a target proxTV::proxTV when using find_package, - # or a library proxTV when using add_subdirectory - set(_proxTV_lib proxTV) # proxTV generated in subdirectory - set(proxTV_DIR_INSTALL "${CMAKE_INSTALL_PREFIX}/${proxTV_INSTALL_CMAKE_DIR}") -endif() -# When this module is loaded by an app, load proxTV too. -set(${PROJECT_NAME}_EXPORT_CODE_INSTALL -"${${PROJECT_NAME}_EXPORT_CODE_INSTALL} -find_package(OpenMP) -set(proxTV_DIR \"${proxTV_DIR_INSTALL}\") -find_package(proxTV REQUIRED CONFIG) + if (proxTV_USE_LAPACK) + set(${PROJECT_NAME}_EXPORT_CODE_BUILD +"${${PROJECT_NAME}_EXPORT_CODE_BUILD} +if(NOT ITK_BINARY_DIR) + find_package(LAPACKE REQUIRED) + find_package(LAPACK REQUIRED) +endif() ") + set(${PROJECT_NAME}_EXPORT_CODE_INSTALL + "${${PROJECT_NAME}_EXPORT_CODE_INSTALL} + find_package(LAPACKE REQUIRED) + find_package(LAPACK REQUIRED) + ") + endif() -set(_populate_include_dirs_for_swig TRUE) -if(${_populate_include_dirs_for_swig}) - # SWIG (wrapping) requires INCLUDE_DIRS - get_target_property(proxTV_INCLUDE_DIRS ${_proxTV_lib} INTERFACE_INCLUDE_DIRECTORIES) - string(REGEX REPLACE - ".*BUILD_INTERFACE:(.*/proxtv_fetch-build/src/include).*" - "\\1" - proxTV_INCLUDE_DIRS_STRIP - ${proxTV_INCLUDE_DIRS}) - # message(STATUS "proxTV_INCLUDE_DIRS: ${proxTV_INCLUDE_DIRS}") - # message(STATUS "proxTV_INCLUDE_DIRS_STRIP: ${proxTV_INCLUDE_DIRS_STRIP}") - set(TotalVariation_INCLUDE_DIRS ${proxTV_INCLUDE_DIRS_STRIP}) endif() @@ -150,6 +93,5 @@ else() itk_module_impl() endif() +itk_module_target(proxTV NAMESPACE proxTV::) -# Add the proxTV library to Modules/Targets/TotalVariationTargets.cmake -itk_module_target(${_proxTV_lib} NO_INSTALL) diff --git a/itk-module-init.cmake b/itk-module-init.cmake index fe45460..473b9bf 100644 --- a/itk-module-init.cmake +++ b/itk-module-init.cmake @@ -1,9 +1,6 @@ option(ITK_USE_SYSTEM_proxTV "Use external proxTV" OFF) mark_as_advanced(ITK_USE_SYSTEM_proxTV) -option(ITK_USE_SYSTEM_EIGEN "Use External Eigen3" OFF) -mark_as_advanced(ITK_USE_SYSTEM_EIGEN) - # In case in the future we switch to use lapack instead of eigen for proxTV. option(TotalVariation_proxTV_USE_EIGEN "proxTV in TotalVariation uses EIGEN" ON) mark_as_advanced(TotalVariation_proxTV_USE_EIGEN) From e58e4b66925e4929c1d69382c3a0cf6a0d37a584 Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Tue, 17 Mar 2026 13:38:27 +0000 Subject: [PATCH 3/4] ENH: Update ITKRemoteModuleBuildTestPackageAction to v6.0b02 --- .github/workflows/build-test-package.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test-package.yml b/.github/workflows/build-test-package.yml index 0dcbde2..a21acb0 100644 --- a/.github/workflows/build-test-package.yml +++ b/.github/workflows/build-test-package.yml @@ -4,10 +4,9 @@ on: [push,pull_request] jobs: cxx-build-workflow: - uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-cxx.yml@v5.4.6 + uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-cxx.yml@v6.0b02 python-build-workflow: - uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package-python.yml@v5.4.6 - with: + uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package-python.yml@v6.0b02 secrets: pypi_password: ${{ secrets.pypi_password }} From 539d0aa37363bd4cfcef9fbd62d7fdf525a9e290 Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Tue, 19 May 2026 19:04:38 +0000 Subject: [PATCH 4/4] ENH: Use ITK's provided Eigen3Config.cmake to find Eigen ITK's module Eigen require an itkeigen prefix to the paths and is not compatible with a system Eigen library without the use of a macro. This patch now restore the use of the vendored Eigen library from the alternative package interface. --- CMakeLists.txt | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 090d46e..27e0bc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,10 +46,9 @@ else() # build proxTV here with the selected Eigen3 # set(CMAKE_CXX_EXTENSIONS OFF) endif() - set(proxTV_Eigen_LIBRARIES ITK::ITKEigen3Module) - set(proxTV_GIT_REPOSITORY "https://github.com/InsightSoftwareConsortium/proxTV.git") set(proxTV_GIT_TAG "for/itk-proxtv-3.3.0-69062fe5") + FetchContent_Declare( proxtv_fetch GIT_REPOSITORY ${proxTV_GIT_REPOSITORY} @@ -57,10 +56,33 @@ else() # build proxTV here with the selected Eigen3 ) # proxTV options: + message(STATUS "TotalVariation_proxTV_USE_EIGEN: ${TotalVariation_proxTV_USE_EIGEN}") if(TotalVariation_proxTV_USE_EIGEN) set(proxTV_USE_LAPACK 0) + if(NOT ITK_USE_SYSTEM_EIGEN) + # Set Eigen3_DIR to the internal Eigen3 used in ITK + set(Eigen3_DIR "${ITKInternalEigen3_DIR}") + message(STATUS "ITKTotalVariation: Using internal ITK Eigen Config found in: ${Eigen3_DIR}") + endif() + find_package(Eigen3 REQUIRED) + set(${PROJECT_NAME}_EXPORT_CODE_INSTALL + "${${PROJECT_NAME}_EXPORT_CODE_INSTALL} + find_package(OpenMP) + set(Eigen3_DIR \"${Eigen3_DIR}\") + find_package(Eigen3 REQUIRED CONFIG) + ") + set(${PROJECT_NAME}_EXPORT_CODE_BUILD + "${${PROJECT_NAME}_EXPORT_CODE_BUILD} + if(NOT ITK_BINARY_DIR) + find_package(OpenMP) + set(Eigen3_DIR \"${Eigen3_DIR}\") + find_package(Eigen3 REQUIRED CONFIG) + endif() + ") else() + # proxTV will be build with external system LAPACK instead of Eigen3 set(proxTV_USE_LAPACK 1) + add_compile_definitions(PROXTV_USE_LAPACK) endif() # end proxTV options