Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libtiff: add LERC support, move C++ lib into separate component #21140

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
100 changes: 75 additions & 25 deletions recipes/libtiff/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from conan import ConanFile
import os
import textwrap

from conan import ConanFile, conan_version
from conan.errors import ConanInvalidConfiguration
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, replace_in_file, rm, rmdir
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, replace_in_file, rmdir, save
from conan.tools.microsoft import is_msvc
from conan.tools.scm import Version
import os

required_conan_version = ">=1.53.0"

Expand All @@ -25,6 +27,7 @@ class LibtiffConan(ConanFile):
"lzma": [True, False],
"jpeg": [False, "libjpeg", "libjpeg-turbo", "mozjpeg"],
"zlib": [True, False],
"lerc": [True, False],
"libdeflate": [True, False],
"zstd": [True, False],
"jbig": [True, False],
Expand All @@ -37,6 +40,7 @@ class LibtiffConan(ConanFile):
"lzma": True,
"jpeg": "libjpeg",
"zlib": True,
"lerc": False,
"libdeflate": True,
"zstd": True,
"jbig": True,
Expand All @@ -50,11 +54,14 @@ def export_sources(self):
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
if Version(self.version) <= "4.5.0":
# test_package.cpp segfaults with older libtiff versions
del self.options.cxx

def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
if not self.options.cxx:
if not self.options.get_safe("cxx"):
self.settings.rm_safe("compiler.cppstd")
self.settings.rm_safe("compiler.libcxx")

Expand All @@ -80,6 +87,8 @@ def requirements(self):
self.requires("zstd/1.5.5")
if self.options.webp:
self.requires("libwebp/1.3.2")
if self.options.lerc:
self.requires("lerc/4.0.4")

def validate(self):
if self.options.libdeflate and not self.options.zlib:
Expand All @@ -103,14 +112,14 @@ def generate(self):
tc.variables["libdeflate"] = self.options.libdeflate
tc.variables["zstd"] = self.options.zstd
tc.variables["webp"] = self.options.webp
tc.variables["lerc"] = False # TODO: add lerc support for libtiff versions >= 4.3.0
tc.variables["lerc"] = self.options.lerc
if Version(self.version) >= "4.5.0":
# Disable tools, test, contrib, man & html generation
tc.variables["tiff-tools"] = False
tc.variables["tiff-tests"] = False
tc.variables["tiff-contrib"] = False
tc.variables["tiff-docs"] = False
tc.variables["cxx"] = self.options.cxx
tc.variables["cxx"] = self.options.get_safe("cxx", False)
# BUILD_SHARED_LIBS must be set in command line because defined upstream before project()
tc.cache_variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
tc.cache_variables["CMAKE_FIND_PACKAGE_PREFER_CONFIG"] = True
Expand All @@ -121,14 +130,16 @@ def generate(self):
deps.set_property("xz_utils", "cmake_target_name", "liblzma::liblzma")
deps.set_property("libdeflate", "cmake_file_name", "Deflate")
deps.set_property("libdeflate", "cmake_target_name", "Deflate::Deflate")
deps.set_property("lerc", "cmake_target_name", "LERC::LERC")
deps.generate()
valgur marked this conversation as resolved.
Show resolved Hide resolved

def _patch_sources(self):
apply_conandata_patches(self)

# remove FindXXXX for conan dependencies
for module in ["Deflate", "JBIG", "JPEG", "LERC", "WebP", "ZSTD", "liblzma", "LibLZMA"]:
rm(self, f"Find{module}.cmake", os.path.join(self.source_folder, "cmake"))
for module in self.source_path.joinpath("cmake").glob("Find*.cmake"):
if module.name != "FindCMath.cmake":
module.unlink()

# Export symbols of tiffxx for msvc shared
replace_in_file(self, os.path.join(self.source_folder, "libtiff", "CMakeLists.txt"),
Expand All @@ -155,38 +166,77 @@ def package(self):
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))

# TODO: to remove in conan v2 once cmake_find_package* generators removed
if conan_version.major == 1:
self._create_cmake_module_alias_targets(
os.path.join(self.package_folder, self._module_file_rel_path),
{
"TIFF::TIFF": "libtiff::tiff",
"TIFF::CXX": "libtiff::tiffxx",
}
)

@property
def _module_file_rel_path(self):
return os.path.join("lib", "cmake", f"conan-official-{self.name}-targets.cmake")

def _create_cmake_module_alias_targets(self, module_file, targets):
content = ""
for alias, aliased in targets.items():
content += textwrap.dedent(f"""\
if(TARGET {aliased} AND NOT TARGET {alias})
add_library({alias} INTERFACE IMPORTED)
set_property(TARGET {alias} PROPERTY INTERFACE_LINK_LIBRARIES {aliased})
endif()
""")
save(self, module_file, content)

def package_info(self):
self.cpp_info.set_property("cmake_find_mode", "both")
self.cpp_info.set_property("cmake_file_name", "TIFF")
self.cpp_info.set_property("cmake_target_name", "TIFF::TIFF")
self.cpp_info.set_property("pkg_config_name", f"libtiff-{Version(self.version).major}")

self.cpp_info.components["tiff"].set_property("cmake_target_name", "TIFF::TIFF")
self.cpp_info.components["tiff"].set_property("pkg_config_name", f"libtiff-{Version(self.version).major}")
suffix = "d" if is_msvc(self) and self.settings.build_type == "Debug" else ""
if self.options.cxx:
self.cpp_info.libs.append(f"tiffxx{suffix}")
self.cpp_info.libs.append(f"tiff{suffix}")
self.cpp_info.components["tiff"].libs.append(f"tiff{suffix}")
if self.settings.os in ["Linux", "Android", "FreeBSD", "SunOS", "AIX"]:
self.cpp_info.system_libs.append("m")
self.cpp_info.components["tiff"].system_libs.append("m")

self.cpp_info.requires = []
if self.options.zlib:
self.cpp_info.requires.append("zlib::zlib")
self.cpp_info.components["tiff"].requires.append("zlib::zlib")
if self.options.libdeflate:
self.cpp_info.requires.append("libdeflate::libdeflate")
self.cpp_info.components["tiff"].requires.append("libdeflate::libdeflate")
if self.options.lzma:
self.cpp_info.requires.append("xz_utils::xz_utils")
self.cpp_info.components["tiff"].requires.append("xz_utils::xz_utils")
if self.options.jpeg == "libjpeg":
self.cpp_info.requires.append("libjpeg::libjpeg")
self.cpp_info.components["tiff"].requires.append("libjpeg::libjpeg")
elif self.options.jpeg == "libjpeg-turbo":
self.cpp_info.requires.append("libjpeg-turbo::jpeg")
self.cpp_info.components["tiff"].requires.append("libjpeg-turbo::jpeg")
elif self.options.jpeg == "mozjpeg":
self.cpp_info.requires.append("mozjpeg::libjpeg")
self.cpp_info.components["tiff"].requires.append("mozjpeg::libjpeg")
if self.options.jbig:
self.cpp_info.requires.append("jbig::jbig")
self.cpp_info.components["tiff"].requires.append("jbig::jbig")
if self.options.zstd:
self.cpp_info.requires.append("zstd::zstd")
self.cpp_info.components["tiff"].requires.append("zstd::zstd")
if self.options.webp:
self.cpp_info.requires.append("libwebp::libwebp")
self.cpp_info.components["tiff"].requires.append("libwebp::webp")
if self.options.lerc:
self.cpp_info.components["tiff"].requires.append("lerc::lerc")

if self.options.get_safe("cxx"):
self.cpp_info.components["tiffxx"].libs.append(f"tiffxx{suffix}")
# https://cmake.org/cmake/help/latest/module/FindTIFF.html#imported-targets
# https://github.com/libsdl-org/libtiff/blob/v4.6.0/libtiff/CMakeLists.txt#L229
self.cpp_info.components["tiffxx"].set_property("cmake_target_name", "TIFF::CXX")
# Note: the project does not export tiffxx as a pkg-config component, this is unofficial
self.cpp_info.components["tiffxx"].set_property("pkg_config_name", f"libtiffxx-{Version(self.version).major}")
self.cpp_info.components["tiffxx"].requires = ["tiff"]

# TODO: to remove in conan v2 once cmake_find_package* & pkg_config generators removed
self.cpp_info.names["cmake_find_package"] = "TIFF"
self.cpp_info.names["cmake_find_package_multi"] = "TIFF"
if conan_version.major == 1:
self.cpp_info.filenames["cmake_find_package"] = "TIFF"
self.cpp_info.filenames["cmake_find_package_multi"] = "TIFF"
self.cpp_info.components["tiff"].build_modules["cmake_find_package"] = [self._module_file_rel_path]
self.cpp_info.components["tiff"].build_modules["cmake_find_package_multi"] = [self._module_file_rel_path]
self.cpp_info.builddirs.append(os.path.join("lib", "cmake"))
15 changes: 10 additions & 5 deletions recipes/libtiff/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
cmake_minimum_required(VERSION 3.1)
project(test_package LANGUAGES C)
cmake_minimum_required(VERSION 3.15)
project(test_package C CXX)

find_package(TIFF REQUIRED)
find_package(TIFF REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE TIFF::TIFF)
add_executable(${PROJECT_NAME}_c test_package.c)
target_link_libraries(${PROJECT_NAME}_c PRIVATE TIFF::TIFF)

if(TARGET TIFF::CXX)
add_executable(${PROJECT_NAME}_cxx test_package.cpp)
target_link_libraries(${PROJECT_NAME}_cxx PRIVATE TIFF::CXX)
endif()
12 changes: 11 additions & 1 deletion recipes/libtiff/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from conan.tools.cmake import CMake, cmake_layout
import os

from conan.tools.files import save, load


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
Expand All @@ -15,12 +17,20 @@ def layout(self):
def requirements(self):
self.requires(self.tested_reference_str)

def generate(self):
save(self, os.path.join(self.generators_folder, "cxx_enabled"),
str(self.dependencies["libtiff"].options.get_safe("cxx_enabled", False)))

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

def test(self):
cxx_enabled = load(self, os.path.join(self.generators_folder, "cxx_enabled")) == "True"
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
bin_path = os.path.join(self.cpp.build.bindir, "test_package_c")
self.run(bin_path, env="conanrun")
if cxx_enabled:
bin_path = os.path.join(self.cpp.build.bindir, "test_package_cxx")
self.run(bin_path, env="conanrun")
11 changes: 11 additions & 0 deletions recipes/libtiff/all/test_package/test_package.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <tiffio.hxx>
#include <fstream>

int main()
{
std::ifstream ifs;
ifs.open("foo.tif");
TIFF* tif = TIFFStreamOpen("foo.tif", &ifs);
TIFFClose(tif);
return 0;
}
7 changes: 5 additions & 2 deletions recipes/libtiff/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "cmake", "cmake_find_package"
generators = "cmake", "cmake_find_package_multi"

def build(self):
cmake = CMake(self)
Expand All @@ -13,5 +13,8 @@ def build(self):

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
bin_path = os.path.join("bin", "test_package_c")
self.run(bin_path, run_environment=True)
if "cxx" in self.options["libtiff"] and self.options["libtiff"].cxx:
bin_path = os.path.join("bin", "test_package_cxx")
self.run(bin_path, run_environment=True)
Loading