diff --git a/recipes/glibmm/all/conandata.yml b/recipes/glibmm/all/conandata.yml index 9134c71e80aa3..171a01a50da60 100644 --- a/recipes/glibmm/all/conandata.yml +++ b/recipes/glibmm/all/conandata.yml @@ -1,4 +1,7 @@ sources: + "2.75.0": + url: "https://download.gnome.org/sources/glibmm/2.75/glibmm-2.75.0.tar.xz" + sha256: "60bb12e66488aa8ce41f0eb2f3612f89f5ddc887e3e4d45498524bf60b266b3d" "2.72.1": url: "https://download.gnome.org/sources/glibmm/2.72/glibmm-2.72.1.tar.xz" sha256: "2a7649a28ab5dc53ac4dabb76c9f61599fbc628923ab6a7dd74bf675d9155cd8" @@ -7,13 +10,24 @@ sources: sha256: "199ace5682d81b15a1d565480b4a950682f2db6402c8aa5dd7217d71edff81d5" patches: + "2.75.0": + - patch_file: "patches/enable_static_libs_2_75_0.patch" + patch_type: portability + patch_description: enable static library build for msvc + - patch_file: "patches/fix_initialization_order_fiasco_2_75_0.patch" + patch_type: bugfix + patch_description: fix initialization order for static library "2.72.1": - patch_file: "patches/enable_static_libs_2_72_1.patch" - base_path: "source_subfolder" + patch_type: portability + patch_description: enable static library build for msvc - patch_file: "patches/fix_initialization_order_fiasco_2_72_1.patch" - base_path: "source_subfolder" + patch_type: bugfix + patch_description: fix initialization order for static library "2.66.4": - patch_file: "patches/enable_static_libs_2_66_4.patch" - base_path: "source_subfolder" + patch_type: portability + patch_description: enable static library build for msvc - patch_file: "patches/fix_initialization_order_fiasco_2_66_4.patch" - base_path: "source_subfolder" + patch_type: bugfix + patch_description: fix initialization order for static library diff --git a/recipes/glibmm/all/conanfile.py b/recipes/glibmm/all/conanfile.py index 6f564ef425241..ea2efe10f2484 100644 --- a/recipes/glibmm/all/conanfile.py +++ b/recipes/glibmm/all/conanfile.py @@ -3,16 +3,27 @@ import shutil from conan import ConanFile -from conan.tools import ( - build, - files, - microsoft, - scm -) from conan.errors import ConanInvalidConfiguration -from conans import Meson, tools +from conan.tools.apple import fix_apple_shared_install_name +from conan.tools.build import check_min_cppstd +from conan.tools.env import VirtualBuildEnv +from conan.tools.files import ( + apply_conandata_patches, + copy, + export_conandata_patches, + get, + replace_in_file, + rename, + rm, + rmdir +) +from conan.tools.gnu import PkgConfigDeps +from conan.tools.layout import basic_layout +from conan.tools.meson import Meson, MesonToolchain +from conan.tools.microsoft import is_msvc, is_msvc_static_runtime +from conan.tools.scm import Version -required_conan_version = ">=1.50.0" +required_conan_version = ">=1.53.0" class GlibmmConan(ConanFile): @@ -25,14 +36,11 @@ class GlibmmConan(ConanFile): settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} - - generators = "pkg_config" - exports_sources = "patches/**" short_paths = True @property def _abi_version(self): - return "2.68" if scm.Version(self.version) >= "2.68.0" else "2.4" + return "2.68" if Version(self.version) >= "2.68.0" else "2.4" @property def _glibmm_lib(self): @@ -42,130 +50,120 @@ def _glibmm_lib(self): def _giomm_lib(self): return f"giomm-{self._abi_version}" - def validate(self): - if hasattr(self, "settings_build") and build.cross_building(self): - raise ConanInvalidConfiguration("Cross-building not implemented") + def export_sources(self): + export_conandata_patches(self) + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + if self.options.shared: + self.options["glib"].shared = True + + def layout(self): + basic_layout(self, src_folder="src") + + def requirements(self): + self.requires("glib/2.75.2") + if self._abi_version == "2.68": + self.requires("libsigcpp/3.0.7") + else: + self.requires("libsigcpp/2.10.8") + + def package_id(self): + if not self.dependencies["glib"].options.shared: + self.info.requires["glib"].full_package_mode() + def validate(self): if self.settings.compiler.get_safe("cppstd"): if self._abi_version == "2.68": - build.check_min_cppstd(self, 17) + check_min_cppstd(self, 17) else: - build.check_min_cppstd(self, 11) + check_min_cppstd(self, 11) - if self.options.shared and not self.options["glib"].shared: + if self.options.shared and not self.dependencies["glib"].options.shared: raise ConanInvalidConfiguration( "Linking a shared library against static glib can cause unexpected behaviour." ) - if self.options["glib"].shared and microsoft.is_msvc_static_runtime(self): - raise ConanInvalidConfiguration( - "Linking shared glib with the MSVC static runtime is not supported" - ) - - @property - def _source_subfolder(self): - return "source_subfolder" - - @property - def _build_subfolder(self): - return "build_subfolder" - - def config_options(self): - if self.settings.os == "Windows": - del self.options.fPIC + if self.dependencies["glib"].options.shared and is_msvc_static_runtime(self): + raise ConanInvalidConfiguration("Linking shared glib with the MSVC static runtime is not supported") def build_requirements(self): - self.build_requires("meson/0.64.1") - self.build_requires("pkgconf/1.9.3") + self.tool_requires("meson/1.0.0") + if not self.conf.get("tools.gnu:pkg_config", check_type=str): + self.tool_requires("pkgconf/1.9.3") - def requirements(self): - self.requires("glib/2.75.0") + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) - if self._abi_version == "2.68": - self.requires("libsigcpp/3.0.7") - else: - self.requires("libsigcpp/2.10.8") + def generate(self): + env = VirtualBuildEnv(self) + env.generate() - def source(self): - files.get(self, **self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder) + deps = PkgConfigDeps(self) + deps.generate() + + tc = MesonToolchain(self) + tc.project_options.update({ + "build-examples": "false", + "build-documentation": "false", + "msvc14x-parallel-installable": "false" + }) + tc.generate() def _patch_sources(self): - files.apply_conandata_patches(self) - meson_build = os.path.join(self._source_subfolder, "meson.build") - files.replace_in_file(self, meson_build, "subdir('tests')", "") - if microsoft.is_msvc(self): + apply_conandata_patches(self) + meson_build = os.path.join(self.source_folder, "meson.build") + replace_in_file(self, meson_build, "subdir('tests')", "") + if is_msvc(self): # GLiBMM_GEN_EXTRA_DEFS_STATIC is not defined anywhere and is not # used anywhere except here # when building a static build !defined(GLiBMM_GEN_EXTRA_DEFS_STATIC) # evaluates to 0 if not self.options.shared: - files.replace_in_file(self, - os.path.join(self._source_subfolder, "tools", - "extra_defs_gen", "generate_extra_defs.h"), - "#if defined (_MSC_VER) && !defined (GLIBMM_GEN_EXTRA_DEFS_STATIC)", - "#if 0", - ) + replace_in_file(self, + os.path.join(self.source_folder, "tools", + "extra_defs_gen", "generate_extra_defs.h"), + "#if defined (_MSC_VER) && !defined (GLIBMM_GEN_EXTRA_DEFS_STATIC)", + "#if 0", + ) # when using cpp_std=c++NM the /permissive- flag is added which # attempts enforcing standard conformant c++ code # the problem is that older versions of Windows SDK is not standard # conformant! see: # https://developercommunity.visualstudio.com/t/error-c2760-in-combaseapih-with-windows-sdk-81-and/185399 - files.replace_in_file(self, meson_build, "cpp_std=c++", "cpp_std=vc++") - - def configure(self): - if self.options.shared: - del self.options.fPIC - if self.options.shared: - self.options["glib"].shared = True + replace_in_file(self, meson_build, "cpp_std=c++", "cpp_std=vc++") def build(self): self._patch_sources() - with tools.environment_append(tools.RunEnvironment(self).vars): - meson = self._configure_meson() - meson.build() - - def _configure_meson(self): meson = Meson(self) - defs = { - "build-examples": "false", - "build-documentation": "false", - "msvc14x-parallel-installable": "false", - "default_library": "shared" if self.options.shared else "static", - } - - meson.configure( - defs=defs, - build_folder=self._build_subfolder, - source_folder=self._source_subfolder, - pkg_config_paths=[self.install_folder], - ) - - return meson + meson.configure() + meson.build() def package(self): - self.copy("COPYING", dst="licenses", src=self._source_subfolder) - meson = self._configure_meson() + def rename_msvc_static_libs(): + lib_folder = os.path.join(self.package_folder, "lib") + rename(self, os.path.join(lib_folder, f"libglibmm-{self._abi_version}.a"), + os.path.join(lib_folder, f"{self._glibmm_lib}.lib")) + rename(self, os.path.join(lib_folder, f"libgiomm-{self._abi_version}.a"), + os.path.join(lib_folder, f"{self._giomm_lib}.lib")) + rename(self, os.path.join(lib_folder, f"libglibmm_generate_extra_defs-{self._abi_version}.a"), + os.path.join(lib_folder, f"glibmm_generate_extra_defs-{self._abi_version}.lib")) + + meson = Meson(self) meson.install() - if microsoft.is_msvc(self): - files.rm(self, "*.pdb", os.path.join(self.package_folder, "bin")) + copy(self, "COPYING", self.source_folder, os.path.join(self.package_folder, "licenses")) + + if is_msvc(self): + rm(self, "*.pdb", os.path.join(self.package_folder, "bin")) if not self.options.shared: - files.rename( - self, - os.path.join(self.package_folder, "lib", f"libglibmm-{self._abi_version}.a"), - os.path.join(self.package_folder, "lib", f"{self._glibmm_lib}.lib") - ) - files.rename( - self, - os.path.join(self.package_folder, "lib", f"libgiomm-{self._abi_version}.a"), - os.path.join(self.package_folder, "lib", f"{self._giomm_lib}.lib") - ) - files.rename( - self, - os.path.join(self.package_folder, "lib", f"libglibmm_generate_extra_defs-{self._abi_version}.a"), - os.path.join(self.package_folder, "lib", f"glibmm_generate_extra_defs-{self._abi_version}.lib"), - ) + rename_msvc_static_libs() for directory in [self._glibmm_lib, self._giomm_lib]: directory_path = os.path.join(self.package_folder, "lib", directory, "include", "*.h") @@ -176,26 +174,18 @@ def package(self): ) for dir_to_remove in ["pkgconfig", self._glibmm_lib, self._giomm_lib]: - files.rmdir(self, os.path.join(self.package_folder, "lib", dir_to_remove)) + rmdir(self, os.path.join(self.package_folder, "lib", dir_to_remove)) + fix_apple_shared_install_name(self) def package_info(self): glibmm_component = f"glibmm-{self._abi_version}" - giomm_component = f"giomm-{self._abi_version}" - self.cpp_info.components[glibmm_component].set_property("pkg_config_name", glibmm_component) self.cpp_info.components[glibmm_component].libs = [glibmm_component] self.cpp_info.components[glibmm_component].includedirs = [os.path.join("include", glibmm_component)] + self.cpp_info.components[glibmm_component].requires = ["glib::gobject-2.0", "libsigcpp::libsigcpp"] - if self._abi_version == "2.68": - self.cpp_info.components[glibmm_component].requires = ["glib::gobject-2.0", "libsigcpp::sigc++"] - else: - self.cpp_info.components[glibmm_component].requires = ["glib::gobject-2.0", "libsigcpp::sigc++-2.0"] - + giomm_component = f"giomm-{self._abi_version}" self.cpp_info.components[giomm_component].set_property("pkg_config_name", giomm_component) self.cpp_info.components[giomm_component].libs = [giomm_component] - self.cpp_info.components[giomm_component].includedirs = [ os.path.join("include", giomm_component)] + self.cpp_info.components[giomm_component].includedirs = [os.path.join("include", giomm_component)] self.cpp_info.components[giomm_component].requires = [glibmm_component, "glib::gio-2.0"] - - def package_id(self): - if not self.options["glib"].shared: - self.info.requires["glib"].full_package_mode() diff --git a/recipes/glibmm/all/patches/enable_static_libs_2_75_0.patch b/recipes/glibmm/all/patches/enable_static_libs_2_75_0.patch new file mode 100644 index 0000000000000..f24c64bb5bd54 --- /dev/null +++ b/recipes/glibmm/all/patches/enable_static_libs_2_75_0.patch @@ -0,0 +1,32 @@ +diff --git a/glib/glibmmconfig.h.meson b/glib/glibmmconfig.h.meson +index ef4753d7..b926720b 100644 +--- a/glib/glibmmconfig.h.meson ++++ b/glib/glibmmconfig.h.meson +@@ -27,7 +27,9 @@ + # if defined(_MSC_VER) + # define GLIBMM_MSC 1 + # define GLIBMM_WIN32 1 +-# define GLIBMM_DLL 1 ++# ifndef GLIBMM_STATIC_LIB ++# define GLIBMM_DLL 1 ++# endif + # elif defined(__CYGWIN__) + # define GLIBMM_CONFIGURE 1 + # elif defined(__MINGW32__) +diff --git a/glib/meson.build b/glib/meson.build +index d16621e9..3eb8bc47 100644 +--- a/glib/meson.build ++++ b/glib/meson.build +@@ -37,12 +37,6 @@ pkg_conf_data.set('MSVC_TOOLSET_VER', msvc14x_toolset_ver) + + library_build_type = get_option('default_library') + +-if cpp_compiler.get_argument_syntax() == 'msvc' +- if library_build_type == 'static' or library_build_type == 'both' +- error('Static builds are not supported by MSVC-style builds') +- endif +-endif +- + if library_build_type == 'static' + pkg_conf_data.set('GLIBMM_STATIC_LIB', 1) + pkg_conf_data.set('GIOMM_STATIC_LIB', 1) diff --git a/recipes/glibmm/all/patches/fix_initialization_order_fiasco_2_75_0.patch b/recipes/glibmm/all/patches/fix_initialization_order_fiasco_2_75_0.patch new file mode 100644 index 0000000000000..6a24ae04d3038 --- /dev/null +++ b/recipes/glibmm/all/patches/fix_initialization_order_fiasco_2_75_0.patch @@ -0,0 +1,84 @@ +diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc +index 31f92c61..f5befb2d 100644 +--- a/glib/glibmm/class.cc ++++ b/glib/glibmm/class.cc +@@ -166,7 +166,11 @@ Class::clone_custom_type( + } + + // Initialize the static quark to store/get custom type properties. ++#if GLIB_STATIC_COMPILATION ++GQuark Class::iface_properties_quark = 0; ++#else + GQuark Class::iface_properties_quark = g_quark_from_string("gtkmm_CustomObject_iface_properties"); ++#endif + + // static + void +diff --git a/glib/glibmm/init.cc b/glib/glibmm/init.cc +index 0b34447d..6b70a4c2 100644 +--- a/glib/glibmm/init.cc ++++ b/glib/glibmm/init.cc +@@ -14,12 +14,17 @@ + * License along with this library. If not, see . + */ + ++#include + #include + #include + #include + #include + #include + ++#if GLIB_STATIC_COMPILATION ++#include ++#endif ++ + namespace + { + bool init_to_users_preferred_locale = true; +@@ -45,6 +50,11 @@ void init() + if (is_initialized) + return; + ++#if GLIB_STATIC_COMPILATION ++ Glib::Class::iface_properties_quark = ++ g_quark_from_string("gtkmm_CustomObject_iface_properties"); ++#endif ++ + if (init_to_users_preferred_locale) + { + try +diff --git a/glib/glibmm/property.cc b/glib/glibmm/property.cc +index 56dad849..630b35b1 100644 +--- a/glib/glibmm/property.cc ++++ b/glib/glibmm/property.cc +@@ -89,8 +89,12 @@ struct custom_properties_type + }; + + // The quark used for storing/getting the custom properties of custom types. +-static const GQuark custom_properties_quark = +- g_quark_from_string("gtkmm_CustomObject_custom_properties"); ++static const GQuark& ++custom_properties_quark() ++{ ++ static GQuark custom_properties_quark_ = g_quark_from_string("gtkmm_CustomObject_custom_properties"); ++ return custom_properties_quark_; ++} + + // Delete the custom properties data when an object of a custom type is finalized. + void destroy_notify_obj_custom_props(void* data) +@@ -111,12 +115,12 @@ custom_properties_type* + get_obj_custom_props(GObject* obj) + { + auto obj_custom_props = +- static_cast(g_object_get_qdata(obj, custom_properties_quark)); ++ static_cast(g_object_get_qdata(obj, custom_properties_quark())); + if (!obj_custom_props) + { + obj_custom_props = new custom_properties_type(); + g_object_set_qdata_full( +- obj, custom_properties_quark, obj_custom_props, destroy_notify_obj_custom_props); ++ obj, custom_properties_quark(), obj_custom_props, destroy_notify_obj_custom_props); + } + return obj_custom_props; + } diff --git a/recipes/glibmm/all/test_package/CMakeLists.txt b/recipes/glibmm/all/test_package/CMakeLists.txt index c47425885e86c..e57ebb60abaed 100644 --- a/recipes/glibmm/all/test_package/CMakeLists.txt +++ b/recipes/glibmm/all/test_package/CMakeLists.txt @@ -1,18 +1,15 @@ cmake_minimum_required(VERSION 3.6) project(test_package) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGET) - find_package(glibmm REQUIRED CONFIG) add_executable(${PROJECT_NAME} test_package.cpp) if (TARGET glibmm::glibmm-2.68) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) - target_link_libraries(${PROJECT_NAME} glibmm::glibmm-2.68 glibmm::giomm-2.68) + target_link_libraries(${PROJECT_NAME} PRIVATE glibmm::glibmm-2.68 glibmm::giomm-2.68) else() set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) - target_link_libraries(${PROJECT_NAME} glibmm::glibmm-2.4 glibmm::giomm-2.4) + target_link_libraries(${PROJECT_NAME} PRIVATE glibmm::glibmm-2.4 glibmm::giomm-2.4) endif() diff --git a/recipes/glibmm/all/test_package/conanfile.py b/recipes/glibmm/all/test_package/conanfile.py index 38f4483872d47..05bb1c8f03b5d 100644 --- a/recipes/glibmm/all/test_package/conanfile.py +++ b/recipes/glibmm/all/test_package/conanfile.py @@ -1,10 +1,21 @@ -from conans import ConanFile, CMake, tools +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import CMake +from conan.tools.layout import cmake_layout + import os class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" - generators = "cmake", "cmake_find_package_multi" + generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" + test_type = "explicit" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) def build(self): cmake = CMake(self) @@ -12,6 +23,6 @@ def build(self): cmake.build() def test(self): - if not tools.cross_building(self): - bin_path = os.path.join("bin", "test_package") - self.run(bin_path, run_environment=True) + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/glibmm/all/test_v1_package/CMakeLists.txt b/recipes/glibmm/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..925ecbe19e448 --- /dev/null +++ b/recipes/glibmm/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/ + ${CMAKE_CURRENT_BINARY_DIR}/test_package/) diff --git a/recipes/glibmm/all/test_v1_package/conanfile.py b/recipes/glibmm/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..38f4483872d47 --- /dev/null +++ b/recipes/glibmm/all/test_v1_package/conanfile.py @@ -0,0 +1,17 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "cmake", "cmake_find_package_multi" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) diff --git a/recipes/glibmm/config.yml b/recipes/glibmm/config.yml index 51960e64ef7eb..6aaa4e9d859bb 100644 --- a/recipes/glibmm/config.yml +++ b/recipes/glibmm/config.yml @@ -1,4 +1,6 @@ versions: + "2.75.0": + folder: "all" "2.72.1": folder: "all" "2.66.4":