dgobbi / vtk-dicom

A set of classes for using DICOM in VTK.
BSD 3-Clause "New" or "Revised" License
258 stars 94 forks source link

CMakeLists should define project after minimum version #229

Closed RobertHabrich closed 4 months ago

RobertHabrich commented 5 months ago

Hi. Just playing around with creating a conan package for this library and ran into some CMake policy errors that are due to an incorrect order of the project and cmake_minimum_required calls in the main CMakeLists.txt.

According to the documentation of the project call (e.g. https://cmake.org/cmake/help/latest/command/project.html at the bottom):

Note Call the project() command near the top of the top-level CMakeLists.txt, but after calling cmake_minimum_required(). It is important to establish version and policy settings before invoking other commands whose behavior they may affect and for this reason the project() command will issue a warning if this order is not kept. See also policy CMP0000.

RobertHabrich commented 5 months ago

Just in case the conan recipe is useful to anyone else, this is my first working version (note that we have internal recipes for vtk and dcmtk, so some adjustments will be needed... also, I only need a Windows version, so that is the only tested platform):

from conan import ConanFile
from conan.tools.cmake import CMakeDeps, CMakeToolchain, CMake, cmake_layout
from conan.tools.files import collect_libs, replace_in_file
from conan.tools.scm import Git

import os

class VtkDicomConan(ConanFile):
    name = "vtk-dicom"
    version = "0.8.15"
    url = "https://github.com/dgobbi/vtk-dicom"

    settings = "os", "compiler", "build_type", "arch"
    options = {}
    default_options = {
        "dcmtk/*:shared": False,
        "dcmtk/*:with_openssl": False,
    }

    def requirements(self):
        self.requires("dcmtk/3.6.8")
        self.requires("vtk/9.2.6")

    def source(self):
        git = Git(self)
        git.clone(url="https://github.com/dgobbi/vtk-dicom.git", target=".")
        git.checkout("v0.8.15")

        # we need to patch the project's CMakeLists; see https://github.com/dgobbi/vtk-dicom/issues/229
        # we just comment out the original project call and put it after cmake_minimum_required
        replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"), "project(DICOM)", "#project(DICOM)")
        replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"), "cmake_minimum_required(VERSION 3.12)", """cmake_minimum_required(VERSION 3.12)
        project(DICOM)""")

    def layout(self):
        cmake_layout(self)

    def generate(self):
        tc = CMakeToolchain(self)
        tc.variables["BUILD_PROGRAMS"] = "OFF"
        tc.variables["USE_DCMTK"] = "ON"
        tc.variables["DCMTK_DIR"] = self.deps_cpp_info["dcmtk"].rootpath.replace("\\", "\\\\")

        vtk_dir = self.deps_cpp_info["vtk"].lib_paths[0]
        vtk_dir = os.path.join(vtk_dir, "cmake", "vtk-9.2")
        vtk_dir = vtk_dir.replace("\\", "\\\\")
        tc.variables["VTK_DIR"] = vtk_dir

        # we don't want/need the vtk version name in vtk-dicom library
        tc.variables["DICOM_VERSIONED_INSTALL"] = "OFF"

        tc.generate()

        deps = CMakeDeps(self)
        deps.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        # default install will create another "vtk" subfolder in the include dir
        # we want to make that subfolder our exposed include directory
        self.cpp_info.includedirs[0] = os.path.join(self.cpp_info.includedirs[0], "vtk")
        self.cpp_info.libs = collect_libs(self)

        # auto-generate find package script for vtk-dicom
        self.cpp_info.set_property("cmake_find_mode", "both")
dgobbi commented 4 months ago

The cmake_minimum_required() has been fixed in the main branch, and will be in the next release (probably late July).