From cbef5f3a122866c5ed2d6cb3d6c9825094ed71dd Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 5 Jul 2023 15:24:14 +0200 Subject: [PATCH 01/31] Ruby: support conan v2 and expose more configuration options for native extension gems. Reboots #12456 and #12208 * conan v2 support (work done by myself + a merge of @SpaceIm 's branch from PR #12208 to reconcile both) * Extend testing to require one of the native extensions * ``` post_package(): WARN: [MISSING SYSTEM LIBS (KB-H043)] Library './lib/ruby/3.1.0/x86_64-linux/pty.so' links to system library 'util' but it is not in cpp_info.system_libs. ``` * Use `--with-opt-dir` instead of `--with-xx-dir` that ruby isn't respecting. conanio/gccXX (eg 10) removed the libxxx-dev (eg libgmp-dev) from the image. This made me realize that the conan deps weren't being picked up by the build. The openssl was, because --with-openssl-dir is explicitly used in ruby config. So here, we rely on --with-opt-dir. cf: https://bugs.ruby-lang.org/issues/19014#change-99241 (--with-gmp-dir was added on September 14, 2022, wrote this in Sep 22, 2022) * Pass both --with-opt-dir and --with-xxx-dir https://gist.github.com/mrkn/6647630 --- recipes/ruby/all/conandata.yml | 4 - recipes/ruby/all/conanfile.py | 223 ++++++++++++------ recipes/ruby/all/test_package/CMakeLists.txt | 17 +- recipes/ruby/all/test_package/conanfile.py | 33 ++- recipes/ruby/all/test_package/test_package.c | 11 - .../ruby/all/test_package/test_package.cpp | 57 +++++ .../ruby/all/test_v1_package/CMakeLists.txt | 26 ++ recipes/ruby/all/test_v1_package/conanfile.py | 30 +++ 8 files changed, 302 insertions(+), 99 deletions(-) delete mode 100644 recipes/ruby/all/test_package/test_package.c create mode 100644 recipes/ruby/all/test_package/test_package.cpp create mode 100644 recipes/ruby/all/test_v1_package/CMakeLists.txt create mode 100644 recipes/ruby/all/test_v1_package/conanfile.py diff --git a/recipes/ruby/all/conandata.yml b/recipes/ruby/all/conandata.yml index 157bd7e6db982..4dbd391211d28 100644 --- a/recipes/ruby/all/conandata.yml +++ b/recipes/ruby/all/conandata.yml @@ -5,10 +5,6 @@ sources: patches: "3.1.0": - patch_file: "patches/0001-darwin-includedir.patch" - base_path: "source_subfolder" - patch_file: "patches/0002-remove-fpic.patch" - base_path: "source_subfolder" - patch_file: "patches/0003-openssl-ext.patch" - base_path: "source_subfolder" - patch_file: "patches/0004-windows-cflags.patch" - base_path: "source_subfolder" diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index ae5f69f7b3f1a..59824ba379b09 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -1,22 +1,18 @@ +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os, to_apple_arch +from conan.tools.build import cross_building +from conan.tools.files import apply_conandata_patches, collect_libs, copy, get, rm, rmdir +from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain +from conan.tools.layout import basic_layout +from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars +from conan.tools.scm import Version + import glob import os import re -from conan import ConanFile -from conan.tools.apple.apple import is_apple_os, to_apple_arch - -try: - from conan.tools.cross_building import cross_building -except ImportError: - from conan.tools.build.cross_building import cross_building - -from conan.tools.files import apply_conandata_patches -from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain -from conan.tools.microsoft import msvc_runtime_flag, is_msvc -from conans import tools -from conans.errors import ConanInvalidConfiguration - -required_conan_version = ">=1.43.0" +required_conan_version = ">=1.51.3" class RubyConan(ConanFile): @@ -27,22 +23,32 @@ class RubyConan(ConanFile): homepage = "https://www.ruby-lang.org" url = "https://github.com/conan-io/conan-center-index" settings = "os", "arch", "compiler", "build_type" - exports_sources = "patches/**" options = { "shared": [True, False], "fPIC": [True, False], - "with_openssl": [True, False] + "with_openssl": [True, False], + + "with_static_linked_ext": [True, False], + "with_enable_load_relative": [True, False], + "with_libyaml": [True, False], + "with_libffi": [True, False], + "with_readline": [True, False], + "with_gmp": [True, False], } default_options = { "shared": False, "fPIC": True, - "with_openssl": True + "with_openssl": True, + + "with_static_linked_ext": True, + "with_enable_load_relative": True, + "with_libyaml": True, + "with_libffi": True, + "with_readline": True, + 'with_gmp': True, } - short_paths = True - @property - def _source_subfolder(self): - return "source_subfolder" + short_paths = True @property def _settings_build(self): @@ -54,39 +60,70 @@ def _windows_system_libs(self): @property def _msvc_optflag(self): - if self.settings.compiler == "Visual Studio" and tools.Version(self.settings.compiler.version) < "14": + if self.settings.compiler == "Visual Studio" and Version(self.settings.compiler.version) < "14": return "-O2b2xg-" else: return "-O2sy-" - def requirements(self): - self.requires("zlib/1.2.12") - self.requires("gmp/6.1.2") - if self.options.with_openssl: - self.requires("openssl/1.1.1o") + def export_sources(self): + for p in self.conan_data.get("patches", {}).get(self.version, []): + copy(self, p["patch_file"], self.recipe_folder, self.export_sources_folder) def config_options(self): if self.settings.os == "Windows": del self.options.fPIC + def configure(self): + if self.options.shared: + del self.options.fPIC + del self.options.with_static_linked_ext + + try: + del self.settings.compiler.libcxx + except Exception: + pass + try: + del self.settings.compiler.cppstd + except Exception: + pass + + if self.settings.os == 'Windows': + # readline isn't supported on Windows + self.options.with_readline = False + + def requirements(self): + self.requires("zlib/1.2.12") + + if self.options.with_openssl: + self.requires("openssl/1.1.1q") + + if self.options.with_libyaml: + self.requires("libyaml/0.2.5") + + if self.options.with_libffi: + self.requires("libffi/3.4.2") + + if self.options.with_readline: + self.requires("readline/8.1.2") + + if self.options.with_gmp: + self.requires("gmp/6.2.1") + def validate(self): - if is_msvc(self) and msvc_runtime_flag(self).startswith('MT'): + if is_msvc(self) and is_msvc_static_runtime(self): # see https://github.com/conan-io/conan-center-index/pull/8644#issuecomment-1068974098 raise ConanInvalidConfiguration("VS static runtime is not supported") - def configure(self): - if self.options.shared: - del self.options.fPIC - del self.settings.compiler.libcxx - del self.settings.compiler.cppstd + def layout(self): + basic_layout(self, src_folder="src") def source(self): - tools.get(**self.conan_data["sources"][self.version], destination=self._source_subfolder, strip_root=True) + get(self, **self.conan_data["sources"][self.version], strip_root=True) def generate(self): td = AutotoolsDeps(self) # remove non-existing frameworks dirs, otherwise clang complains - for m in re.finditer("-F (\S+)", td.vars().get("LDFLAGS")): + for m in re.finditer(r"-F (\S+)", td.vars().get("LDFLAGS")): if not os.path.exists(m[1]): td.environment.remove("LDFLAGS", f"-F {m[1]}") if self.settings.os == "Windows": @@ -97,8 +134,6 @@ def generate(self): td.generate() tc = AutotoolsToolchain(self) - # TODO: removed in conan 1.49 - tc.default_configure_install_args = True tc.configure_args.append("--disable-install-doc") if self.options.shared and not is_msvc(self): @@ -107,7 +142,25 @@ def generate(self): if "--enable-shared" not in tc.configure_args: tc.configure_args.append("--enable-shared") - if cross_building(self) and is_apple_os(self.settings.os): + if not self.options.shared and self.options.with_static_linked_ext: + tc.configure_args.append('--with-static-linked-ext') + + if self.options.with_enable_load_relative: + tc.configure_args.append('--enable-load-relative') + + # Ruby doesn't respect the --with-gmp-dir for eg. After removal of libgmp-dev on conanio/gcc10 build failed + opt_dirs = [] + for name, dep_cpp_info in self.deps_cpp_info.dependencies: + if name in ['zlib', 'openssl', 'libffi', 'libyaml', 'readline', 'gmp']: + root_path = unix_path(self, dep_cpp_info.rootpath) + tc.configure_args.append(f'--with-{name}-dir={root_path}') + opt_dirs.append(root_path) + if opt_dirs: + sep = ';' if self.settings.os == "Windows" else ":" + + tc.configure_args.append(f"--with-opt-dir={sep.join(opt_dirs)}") + + if cross_building(self) and is_apple_os(self): apple_arch = to_apple_arch(self.settings.arch) if apple_arch: tc.configure_args.append(f"--with-arch={apple_arch}") @@ -122,12 +175,16 @@ def generate(self): tc.generate() + if is_msvc(self): + vc = VCVars(self) + vc.generate() + def build(self): apply_conandata_patches(self) - at = Autotools(self) + autotools = Autotools(self) - build_script_folder = self._source_subfolder + build_script_folder = self.source_folder if is_msvc(self): self.conf["tools.gnu:make_program"] = "nmake" build_script_folder = os.path.join(build_script_folder, "win32") @@ -135,62 +192,80 @@ def build(self): if "TMP" in os.environ: # workaround for TMP in CCI containing both forward and back slashes os.environ["TMP"] = os.environ["TMP"].replace("/", "\\") - with tools.vcvars(self): - at.configure(build_script_folder=build_script_folder) - at.make() + autotools.configure(build_script_folder=build_script_folder) + autotools.make() def package(self): for file in ["COPYING", "BSDL"]: - self.copy(file, dst="licenses", src=self._source_subfolder) + copy(self, pattern=file, src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) - at = Autotools(self) - with tools.vcvars(self): - if cross_building(self): - at.make(target="install-local") - at.make(target="install-arch") - else: - at.install() + autotools = Autotools(self) + if cross_building(self): + autotools.make(target="install-local") + autotools.make(target="install-arch") + else: + autotools.install() + + rmdir(self, os.path.join(self.package_folder, "share")) + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + rm(self, pattern="*.pdb", folder=os.path.join(self.package_folder, "lib")) - tools.rmdir(os.path.join(self.package_folder, "share")) - tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig")) - tools.remove_files_by_mask(os.path.join(self.package_folder, "lib"), "*.pdb") + # install the enc/*.a / ext/*.a libraries + if not self.options.shared and self.options.with_static_linked_ext: + for dirname in ['ext', 'enc']: + dst = os.path.join('lib', dirname) + copy(self, '*.a', src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) + copy(self, '*.lib', src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) def package_info(self): binpath = os.path.join(self.package_folder, "bin") self.output.info(f"Adding to PATH: {binpath}") self.env_info.PATH.append(binpath) - version = tools.Version(self.version) - rubylib = self.cpp_info.components["rubylib"] + version = Version(self.version) config_file = glob.glob(os.path.join(self.package_folder, "include", "**", "ruby", "config.h"), recursive=True)[0] - rubylib.includedirs = [ + self.cpp_info.includedirs = [ os.path.join(self.package_folder, "include", f"ruby-{version}"), os.path.dirname(os.path.dirname(config_file)) ] - rubylib.libs = tools.collect_libs(self) + self.cpp_info.libs = collect_libs(self) if is_msvc(self): if self.options.shared: - rubylib.libs = list(filter(lambda l: not l.endswith("-static"), rubylib.libs)) + self.cpp_info.libs = list(filter(lambda l: not l.endswith("-static"), self.cpp_info.libs)) else: - rubylib.libs = list(filter(lambda l: l.endswith("-static"), rubylib.libs)) - rubylib.requires.extend(["zlib::zlib", "gmp::gmp"]) - if self.options.with_openssl: - rubylib.requires.append("openssl::openssl") + self.cpp_info.libs = list(filter(lambda l: l.endswith("-static"), self.cpp_info.libs)) + if self.settings.os in ("FreeBSD", "Linux"): - rubylib.system_libs = ["dl", "pthread", "rt", "m", "crypt"] + self.cpp_info.system_libs = ["dl", "pthread", "rt", "m", "crypt", "util"] elif self.settings.os == "Windows": - rubylib.system_libs = self._windows_system_libs + self.cpp_info.system_libs = self._windows_system_libs if str(self.settings.compiler) in ("clang", "apple-clang"): - rubylib.cflags = ["-fdeclspec"] - rubylib.cxxflags = ["-fdeclspec"] - if tools.is_apple_os(self.settings.os): - rubylib.frameworks = ["CoreFoundation"] + self.cpp_info.cflags = ["-fdeclspec"] + self.cpp_info.cxxflags = ["-fdeclspec"] + if is_apple_os(self): + self.cpp_info.frameworks = ["CoreFoundation"] - self.cpp_info.filenames["cmake_find_package"] = "Ruby" - self.cpp_info.filenames["cmake_find_package_multi"] = "Ruby" + self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", "Ruby") + self.cpp_info.set_property("cmake_target_name", "Ruby::Ruby") + self.cpp_info.set_property("pkg_config_name", "ruby") + self.cpp_info.set_property("pkg_config_aliases", [f"ruby-{version.major}.{version.minor}"]) + # TODO: remove this block if required_conan_version changed to 1.51.1 or higher + # (see https://github.com/conan-io/conan/pull/11790) + # TODO: if --with-static-linked-ext is passed, is this necessary anyways? + self.cpp_info.requires.append("zlib::zlib") + if self.options.with_gmp: + self.cpp_info.requires.append("gmp::gmp") + if self.options.with_openssl: + self.cpp_info.requires.append("openssl::openssl") + if self.options.with_libyaml: + self.cpp_info.requires.append("libyaml::libyaml") + if self.options.with_libffi: + self.cpp_info.requires.append("libffi::libffi") + if self.options.with_readline: + self.cpp_info.requires.append("readline::readline") + + # TODO: to remove in conan v2 self.cpp_info.names["cmake_find_package"] = "Ruby" self.cpp_info.names["cmake_find_package_multi"] = "Ruby" - self.cpp_info.set_property("cmake_target_name", "Ruby::Ruby") - self.cpp_info.set_property("pkg_config_aliases", [f"ruby-{version.major}.{version.minor}"]) diff --git a/recipes/ruby/all/test_package/CMakeLists.txt b/recipes/ruby/all/test_package/CMakeLists.txt index 361d2a449e95c..55e2e39746e22 100644 --- a/recipes/ruby/all/test_package/CMakeLists.txt +++ b/recipes/ruby/all/test_package/CMakeLists.txt @@ -1,10 +1,23 @@ cmake_minimum_required(VERSION 3.1) -project(test_package C) +project(test_package LANGUAGES CXX) find_package(Ruby REQUIRED) -add_executable(${PROJECT_NAME} test_package.c) +add_executable(${PROJECT_NAME} test_package.cpp) +set_target_properties(${PROJECT_NAME} + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF +) + target_link_libraries(${PROJECT_NAME} Ruby::Ruby) +if (RUBY_STATIC_RUBY) + target_compile_definitions(${PROJECT_NAME} PRIVATE RUBY_STATIC_RUBY) +endif() +if (RUBY_STATIC_LINKED_EXT) + target_compile_definitions(${PROJECT_NAME} PRIVATE RUBY_STATIC_LINKED_EXT) +endif() set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin) set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}/bin) set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_BINARY_DIR}/bin) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 20f8f26c4f735..3c4aa957b2d58 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -1,21 +1,38 @@ from conan import ConanFile -from conan.tools.cmake import CMake -from conans import tools +from conan.tools.build import cross_building +from conan.tools.cmake import CMake, cmake_layout import os + class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "CMakeDeps", "CMakeToolchain" + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) - cmake.configure() + # when --static-linked-ext is used, ruby defines EXTSTATIC as 1 + # But when ruby itself is static there's nothing, so: + # We define RUBY_STATIC_RUBY when ruby itself is static + # We define RUBY_STATIC_LINKED_EXT when the ruby extensions are static (same as EXTSTATIC but clearer) + defs = {} + if not self.options['ruby'].shared: + defs['RUBY_STATIC_RUBY'] = 1 + if self.options['ruby'].with_static_linked_ext: + defs['RUBY_STATIC_LINKED_EXT'] = 1 + cmake.configure(variables=defs) cmake.build() def test(self): - if not tools.cross_building(self): + if not cross_building(self): # test executable - self.run("ruby --version", run_environment=True) + self.run("ruby --version", env="conanrun") # test library - self.run(os.path.join("bin", "test_package"), run_environment=True) + bin_path = os.path.join(self.cpp.build.bindirs[0], "bin", "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/ruby/all/test_package/test_package.c b/recipes/ruby/all/test_package/test_package.c deleted file mode 100644 index 12210d7a1f569..0000000000000 --- a/recipes/ruby/all/test_package/test_package.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -int main(int argc, char* argv[]) { - ruby_sysinit(&argc, &argv); - RUBY_INIT_STACK; - ruby_init(); - - rb_eval_string("puts 'Hello, ruby!'"); - - return EXIT_SUCCESS; -} diff --git a/recipes/ruby/all/test_package/test_package.cpp b/recipes/ruby/all/test_package/test_package.cpp new file mode 100644 index 0000000000000..e496de7e51322 --- /dev/null +++ b/recipes/ruby/all/test_package/test_package.cpp @@ -0,0 +1,57 @@ +#include + +// when --static-linked-ext is used, ruby defines EXTSTATIC as 1 +#if defined(EXTSTATIC) && EXTSTATIC +# define RUBY_STATIC_LINKED_EXT2 +#else +# undef RUBY_STATIC_LINKED_EXT2 +#endif + +int main(int argc, char* argv[]) { + ruby_sysinit(&argc, &argv); + RUBY_INIT_STACK; + ruby_init(); + + rb_eval_string("puts 'Hello, ruby!'"); + +#ifdef RUBY_STATIC_RUBY + rb_eval_string("puts 'Ruby itself is statically linked'"); +#else + rb_eval_string("puts 'Ruby itself is dynamically linked'"); +#endif + +#ifdef RUBY_STATIC_LINKED_EXT + rb_eval_string("puts 'Ruby has statically linked extensions'"); +#else + rb_eval_string("puts 'Ruby has dynamically linked extensions'"); +#endif + +#ifdef RUBY_STATIC_LINKED_EXT2 + rb_eval_string("puts 'Ruby has statically linked extensions (EXTSTATIC)'"); +#else + rb_eval_string("puts 'Ruby has dynamically linked extensions (EXTSTATIC)'"); +#endif + +#ifdef RUBY_STATIC_RUBY + rb_provide("bigdecimal"); + rb_provide("bigdecimal.so"); +#else + ruby_init_loadpath(); +#endif + + rb_eval_string(R"( + begin + (require 'bigdecimal') + puts "I can correctly load one of the extension gems - bigdecimal" + rescue Exception => e + puts + puts "Error: #{e.message}" + puts "Backtrace:\n\t" + e.backtrace.join("\n\t") + raise + end + )"); + + ruby_finalize(); + + return EXIT_SUCCESS; +} diff --git a/recipes/ruby/all/test_v1_package/CMakeLists.txt b/recipes/ruby/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..819b03cd0d186 --- /dev/null +++ b/recipes/ruby/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package LANGUAGES CXX) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +find_package(Ruby REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} ../test_package/test_package.cpp) +set_target_properties(${PROJECT_NAME} + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF +) +target_link_libraries(${PROJECT_NAME} PRIVATE Ruby::Ruby) +if (RUBY_STATIC_RUBY) + target_compile_definitions(${PROJECT_NAME} PRIVATE RUBY_STATIC_RUBY) +endif() +if (RUBY_STATIC_LINKED_EXT) + target_compile_definitions(${PROJECT_NAME} PRIVATE RUBY_STATIC_LINKED_EXT) +endif() +set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin) +set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}/bin) +set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_BINARY_DIR}/bin) +set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin) diff --git a/recipes/ruby/all/test_v1_package/conanfile.py b/recipes/ruby/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..58f9a8b61ed68 --- /dev/null +++ b/recipes/ruby/all/test_v1_package/conanfile.py @@ -0,0 +1,30 @@ +# pylint: skip-file +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) + # when --static-linked-ext is used, ruby defines EXTSTATIC as 1 + # But when ruby itself is static there's nothing, so: + # We define RUBY_STATIC_RUBY when ruby itself is static + # We define RUBY_STATIC_LINKED_EXT when the ruby extensions are static (same as EXTSTATIC but clearer) + if not self.options['ruby'].shared: + cmake.definitions['RUBY_STATIC_RUBY'] = 1 + if self.options['ruby'].with_static_linked_ext: + cmake.definitions['RUBY_STATIC_LINKED_EXT'] = 1 + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self): + # test executable + self.run("ruby --version", run_environment=True) + + # test library + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) From 53d792269568a4f41600da50ef874326644aebc5 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 5 Jul 2023 16:51:59 +0200 Subject: [PATCH 02/31] Make changes for 2.0.7 --- recipes/ruby/all/conanfile.py | 13 ++++++++----- recipes/ruby/all/test_package/conanfile.py | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 59824ba379b09..d478600c254e8 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -150,14 +150,17 @@ def generate(self): # Ruby doesn't respect the --with-gmp-dir for eg. After removal of libgmp-dev on conanio/gcc10 build failed opt_dirs = [] - for name, dep_cpp_info in self.deps_cpp_info.dependencies: - if name in ['zlib', 'openssl', 'libffi', 'libyaml', 'readline', 'gmp']: - root_path = unix_path(self, dep_cpp_info.rootpath) - tc.configure_args.append(f'--with-{name}-dir={root_path}') + + # zlib always True + tc.configure_args.append(f'--with-zlib-dir={self.dependencies["zlib"].package_path.as_posix()}') + for dep in ['zlib', 'openssl', 'libffi', 'libyaml', 'readline', 'gmp']: + if self.options.get_safe(f'with_{dep}'): + root_path = self.dependencies[dep].package_path.as_posix() + tc.configure_args.append(f'--with-{dep}-dir={root_path}') opt_dirs.append(root_path) + if opt_dirs: sep = ';' if self.settings.os == "Windows" else ":" - tc.configure_args.append(f"--with-opt-dir={sep.join(opt_dirs)}") if cross_building(self) and is_apple_os(self): diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 3c4aa957b2d58..55b30c6626f1f 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -21,9 +21,10 @@ def build(self): # We define RUBY_STATIC_RUBY when ruby itself is static # We define RUBY_STATIC_LINKED_EXT when the ruby extensions are static (same as EXTSTATIC but clearer) defs = {} - if not self.options['ruby'].shared: + tested_options = self.dependencies[self.tested_reference_str].options + if not tested_options.shared: defs['RUBY_STATIC_RUBY'] = 1 - if self.options['ruby'].with_static_linked_ext: + if tested_options.with_static_linked_ext: defs['RUBY_STATIC_LINKED_EXT'] = 1 cmake.configure(variables=defs) cmake.build() From ec79200282c94d06f8b8863052548dc0c1c5b7ce Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 28 Aug 2023 11:13:06 +0200 Subject: [PATCH 03/31] Delete option instead of forcing it to false CI Complains: "ConanException: Incorrect attempt to modify option 'with_readline' from 'True' to 'False'" --- recipes/ruby/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index d478600c254e8..5f9a232e65c69 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -89,7 +89,7 @@ def configure(self): if self.settings.os == 'Windows': # readline isn't supported on Windows - self.options.with_readline = False + del self.options.with_readline def requirements(self): self.requires("zlib/1.2.12") From e551968eb71e36786fc9172563ab6fe5357cb6e7 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 18 Dec 2023 18:08:28 +0100 Subject: [PATCH 04/31] Remove pylint: skip-file --- recipes/ruby/all/test_v1_package/conanfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/recipes/ruby/all/test_v1_package/conanfile.py b/recipes/ruby/all/test_v1_package/conanfile.py index 58f9a8b61ed68..3e7f71d56b728 100644 --- a/recipes/ruby/all/test_v1_package/conanfile.py +++ b/recipes/ruby/all/test_v1_package/conanfile.py @@ -1,4 +1,3 @@ -# pylint: skip-file from conans import ConanFile, CMake, tools import os From 367787be8a10a3f6fe488381fe110f893bff7ce9 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 19 Dec 2023 14:45:05 +0100 Subject: [PATCH 05/31] Adjust testing for conan v2 --- recipes/ruby/all/test_package/conanfile.py | 40 +++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 55b30c6626f1f..20fb280abbc6c 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -1,7 +1,10 @@ +import os +import re +from io import StringIO + from conan import ConanFile -from conan.tools.build import cross_building +from conan.tools.build import can_run from conan.tools.cmake import CMake, cmake_layout -import os class TestPackageConan(ConanFile): @@ -9,7 +12,7 @@ class TestPackageConan(ConanFile): generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" def requirements(self): - self.requires(self.tested_reference_str) + self.requires(self.tested_reference_str, run=True, libs=True) def layout(self): cmake_layout(self) @@ -23,16 +26,37 @@ def build(self): defs = {} tested_options = self.dependencies[self.tested_reference_str].options if not tested_options.shared: - defs['RUBY_STATIC_RUBY'] = 1 + defs["RUBY_STATIC_RUBY"] = 1 if tested_options.with_static_linked_ext: - defs['RUBY_STATIC_LINKED_EXT'] = 1 + defs["RUBY_STATIC_LINKED_EXT"] = 1 cmake.configure(variables=defs) cmake.build() + def build_requirements(self): + self.tool_requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) + + def _ruby_version(self): + tokens = re.split("[@#]", self.tested_reference_str) + return tokens[0].split("/", 1)[1] + + def _test_ruby_executable(self): + # test executable + output = StringIO() + self.run("ruby --version", output, env="conanrun") + output_str = str(output.getvalue()).strip() + self.output.info("Installed version: {}".format(output_str)) + tokens = re.split("[@#]", self.tested_reference_str) + require_version = tokens[0].split("/", 1)[1] + self.output.info("Expected version: {}".format(self._ruby_version())) + assert_ruby_version = "ruby {}".format(self._ruby_version()) + assert assert_ruby_version in output_str + def test(self): - if not cross_building(self): - # test executable - self.run("ruby --version", env="conanrun") + if can_run(self): + self._test_ruby_executable() # test library bin_path = os.path.join(self.cpp.build.bindirs[0], "bin", "test_package") From 5eed04718af848c0be35322e0cd2f5eeabb867cf Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 19 Dec 2023 14:52:34 +0100 Subject: [PATCH 06/31] Use f-strings per the linter. --- recipes/ruby/all/test_package/conanfile.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 20fb280abbc6c..e18797f376164 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -32,12 +32,6 @@ def build(self): cmake.configure(variables=defs) cmake.build() - def build_requirements(self): - self.tool_requires(self.tested_reference_str) - - def layout(self): - cmake_layout(self) - def _ruby_version(self): tokens = re.split("[@#]", self.tested_reference_str) return tokens[0].split("/", 1)[1] @@ -47,11 +41,9 @@ def _test_ruby_executable(self): output = StringIO() self.run("ruby --version", output, env="conanrun") output_str = str(output.getvalue()).strip() - self.output.info("Installed version: {}".format(output_str)) - tokens = re.split("[@#]", self.tested_reference_str) - require_version = tokens[0].split("/", 1)[1] - self.output.info("Expected version: {}".format(self._ruby_version())) - assert_ruby_version = "ruby {}".format(self._ruby_version()) + self.output.info(f"Installed version: {output_str}") + assert_ruby_version = f"ruby {self._ruby_version()}" + self.output.info(f"Expected version: {assert_ruby_version}") assert assert_ruby_version in output_str def test(self): From f683111a8ffabe3237108ab159d77262d5f28a94 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 19 Dec 2023 15:58:13 +0100 Subject: [PATCH 07/31] Apply review comments from @valgur --- recipes/ruby/all/conanfile.py | 82 +++++++++++++---------------------- 1 file changed, 30 insertions(+), 52 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 5f9a232e65c69..9a3dee1669956 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -2,7 +2,7 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.apple import is_apple_os, to_apple_arch from conan.tools.build import cross_building -from conan.tools.files import apply_conandata_patches, collect_libs, copy, get, rm, rmdir +from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, rm, rmdir from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars @@ -12,7 +12,7 @@ import os import re -required_conan_version = ">=1.51.3" +required_conan_version = ">=1.53" class RubyConan(ConanFile): @@ -45,7 +45,7 @@ class RubyConan(ConanFile): "with_libyaml": True, "with_libffi": True, "with_readline": True, - 'with_gmp': True, + "with_gmp": True, } short_paths = True @@ -66,8 +66,7 @@ def _msvc_optflag(self): return "-O2sy-" def export_sources(self): - for p in self.conan_data.get("patches", {}).get(self.version, []): - copy(self, p["patch_file"], self.recipe_folder, self.export_sources_folder) + export_conandata_patches(self) def config_options(self): if self.settings.os == "Windows": @@ -78,16 +77,10 @@ def configure(self): del self.options.fPIC del self.options.with_static_linked_ext - try: - del self.settings.compiler.libcxx - except Exception: - pass - try: - del self.settings.compiler.cppstd - except Exception: - pass + self.settings.rm_safe("compiler.libcxx") + self.settings.rm_safe("compiler.cppstd") - if self.settings.os == 'Windows': + if self.settings.os == "Windows": # readline isn't supported on Windows del self.options.with_readline @@ -103,7 +96,7 @@ def requirements(self): if self.options.with_libffi: self.requires("libffi/3.4.2") - if self.options.with_readline: + if self.options.get_safe("with_readline"): self.requires("readline/8.1.2") if self.options.with_gmp: @@ -143,24 +136,24 @@ def generate(self): tc.configure_args.append("--enable-shared") if not self.options.shared and self.options.with_static_linked_ext: - tc.configure_args.append('--with-static-linked-ext') + tc.configure_args.append("--with-static-linked-ext") if self.options.with_enable_load_relative: - tc.configure_args.append('--enable-load-relative') + tc.configure_args.append("--enable-load-relative") # Ruby doesn't respect the --with-gmp-dir for eg. After removal of libgmp-dev on conanio/gcc10 build failed opt_dirs = [] # zlib always True tc.configure_args.append(f'--with-zlib-dir={self.dependencies["zlib"].package_path.as_posix()}') - for dep in ['zlib', 'openssl', 'libffi', 'libyaml', 'readline', 'gmp']: - if self.options.get_safe(f'with_{dep}'): + for dep in ["zlib", "openssl", "libffi", "libyaml", "readline", "gmp"]: + if self.options.get_safe(f"with_{dep}"): root_path = self.dependencies[dep].package_path.as_posix() - tc.configure_args.append(f'--with-{dep}-dir={root_path}') + tc.configure_args.append(f"--with-{dep}-dir={root_path}") opt_dirs.append(root_path) if opt_dirs: - sep = ';' if self.settings.os == "Windows" else ":" + sep = ";" if self.settings.os == "Windows" else ":" tc.configure_args.append(f"--with-opt-dir={sep.join(opt_dirs)}") if cross_building(self) and is_apple_os(self): @@ -215,21 +208,25 @@ def package(self): # install the enc/*.a / ext/*.a libraries if not self.options.shared and self.options.with_static_linked_ext: - for dirname in ['ext', 'enc']: - dst = os.path.join('lib', dirname) - copy(self, '*.a', src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) - copy(self, '*.lib', src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) + for dirname in ["ext", "enc"]: + dst = os.path.join("lib", dirname) + copy(self, "*.a", src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) + copy(self, "*.lib", src=dirname, dst=os.path.join(self.package_folder, dst), keep_path=True) def package_info(self): - binpath = os.path.join(self.package_folder, "bin") - self.output.info(f"Adding to PATH: {binpath}") - self.env_info.PATH.append(binpath) - version = Version(self.version) - config_file = glob.glob(os.path.join(self.package_folder, "include", "**", "ruby", "config.h"), recursive=True)[0] + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_file_name", "Ruby") + self.cpp_info.set_property("cmake_target_name", "Ruby::Ruby") + self.cpp_info.set_property("pkg_config_name", "ruby") + self.cpp_info.set_property("pkg_config_aliases", [f"ruby-{version.major}.{version.minor}"]) + + config_file = glob.glob(os.path.join(self.package_folder, "include", "**", "ruby", "config.h"), recursive=True)[ + 0 + ] self.cpp_info.includedirs = [ os.path.join(self.package_folder, "include", f"ruby-{version}"), - os.path.dirname(os.path.dirname(config_file)) + os.path.dirname(os.path.dirname(config_file)), ] self.cpp_info.libs = collect_libs(self) if is_msvc(self): @@ -248,27 +245,8 @@ def package_info(self): if is_apple_os(self): self.cpp_info.frameworks = ["CoreFoundation"] - self.cpp_info.set_property("cmake_find_mode", "both") - self.cpp_info.set_property("cmake_file_name", "Ruby") - self.cpp_info.set_property("cmake_target_name", "Ruby::Ruby") - self.cpp_info.set_property("pkg_config_name", "ruby") - self.cpp_info.set_property("pkg_config_aliases", [f"ruby-{version.major}.{version.minor}"]) - - # TODO: remove this block if required_conan_version changed to 1.51.1 or higher - # (see https://github.com/conan-io/conan/pull/11790) - # TODO: if --with-static-linked-ext is passed, is this necessary anyways? - self.cpp_info.requires.append("zlib::zlib") - if self.options.with_gmp: - self.cpp_info.requires.append("gmp::gmp") - if self.options.with_openssl: - self.cpp_info.requires.append("openssl::openssl") - if self.options.with_libyaml: - self.cpp_info.requires.append("libyaml::libyaml") - if self.options.with_libffi: - self.cpp_info.requires.append("libffi::libffi") - if self.options.with_readline: - self.cpp_info.requires.append("readline::readline") - # TODO: to remove in conan v2 self.cpp_info.names["cmake_find_package"] = "Ruby" self.cpp_info.names["cmake_find_package_multi"] = "Ruby" + binpath = os.path.join(self.package_folder, "bin") + self.env_info.PATH.append(binpath) From a0a0c434a6e6d8cb98528143e61f560b72cbebe5 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 19 Dec 2023 15:59:20 +0100 Subject: [PATCH 08/31] Improve testing Thanks to Sam on Slack. --- recipes/ruby/all/test_package/conanfile.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index e18797f376164..dc55d277cc5ca 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -12,7 +12,10 @@ class TestPackageConan(ConanFile): generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" def requirements(self): - self.requires(self.tested_reference_str, run=True, libs=True) + self.requires(self.tested_reference_str) + + def build_requirements(self): + self.tool_requires(self.tested_reference_str) def layout(self): cmake_layout(self) @@ -36,20 +39,29 @@ def _ruby_version(self): tokens = re.split("[@#]", self.tested_reference_str) return tokens[0].split("/", 1)[1] - def _test_ruby_executable(self): + def _test_ruby_executable_version(self): # test executable output = StringIO() - self.run("ruby --version", output, env="conanrun") + self.run("ruby --version", output, env="conanbuild") output_str = str(output.getvalue()).strip() self.output.info(f"Installed version: {output_str}") assert_ruby_version = f"ruby {self._ruby_version()}" self.output.info(f"Expected version: {assert_ruby_version}") assert assert_ruby_version in output_str + def _test_ruby_execute(self): + # test executable + output = StringIO() + self.run('ruby -e "puts RUBY_VERSION"', output, env="conanbuild") + output_str = str(output.getvalue()).strip() + self.output.info(f'ruby -e "PUTS RUBY_VERSION": {output_str}') + assert output_str == self._ruby_version() + def test(self): - if can_run(self): - self._test_ruby_executable() + self._test_ruby_executable_version() + self._test_ruby_execute() + if can_run(self): # test library bin_path = os.path.join(self.cpp.build.bindirs[0], "bin", "test_package") self.run(bin_path, env="conanrun") From 2798b4fc71ba8e38e8b2c670b0f9c7c22aafe9e6 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 20 Dec 2023 00:47:11 +0100 Subject: [PATCH 09/31] Fixup removing frameworks dir on mac On my machine, M1 mac with conan 1.61.0 it's not `-F ` but `-F""` eg: `-F"/Users/julien/.conan/data/readline/8.1.2/_/_/package/9fcc18689922974ad28edb46b427da2559f4e6c8/Frameworks ...` --- recipes/ruby/all/conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 9a3dee1669956..3cb7dfa525f35 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -116,9 +116,9 @@ def source(self): def generate(self): td = AutotoolsDeps(self) # remove non-existing frameworks dirs, otherwise clang complains - for m in re.finditer(r"-F (\S+)", td.vars().get("LDFLAGS")): + for m in re.finditer(r'-F(?: |\")([^\r\n\t\f\v\" ]+)\"?', td.vars().get("LDFLAGS")): if not os.path.exists(m[1]): - td.environment.remove("LDFLAGS", f"-F {m[1]}") + td.environment.remove("LDFLAGS", m[0]) if self.settings.os == "Windows": if is_msvc(self): td.environment.append("LIBS", [f"{lib}.lib" for lib in self._windows_system_libs]) From 80fc1a5f754dfcdf145a23c0f3def4d789a8754c Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 20 Dec 2023 01:13:17 +0100 Subject: [PATCH 10/31] Rename test exe to test_v1_package for clarity --- recipes/ruby/all/test_v1_package/CMakeLists.txt | 2 +- recipes/ruby/all/test_v1_package/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/test_v1_package/CMakeLists.txt b/recipes/ruby/all/test_v1_package/CMakeLists.txt index 819b03cd0d186..548cc4dea02a3 100644 --- a/recipes/ruby/all/test_v1_package/CMakeLists.txt +++ b/recipes/ruby/all/test_v1_package/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -project(test_package LANGUAGES CXX) +project(test_v1_package LANGUAGES CXX) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup(TARGETS) diff --git a/recipes/ruby/all/test_v1_package/conanfile.py b/recipes/ruby/all/test_v1_package/conanfile.py index 3e7f71d56b728..c34a1e15dd0ab 100644 --- a/recipes/ruby/all/test_v1_package/conanfile.py +++ b/recipes/ruby/all/test_v1_package/conanfile.py @@ -25,5 +25,5 @@ def test(self): self.run("ruby --version", run_environment=True) # test library - bin_path = os.path.join("bin", "test_package") + bin_path = os.path.join("bin", "test_v1_package") self.run(bin_path, run_environment=True) From 175a786767a216c8d564485620967670af7b46ae Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 20 Dec 2023 02:59:07 +0100 Subject: [PATCH 11/31] Find libcrytod (notice the trailing d) on windows debug + zlibstatic / zlibstaticd too --- recipes/ruby/all/conandata.yml | 6 ++- .../ruby/all/patches/0003-openssl-ext.patch | 13 ------- .../all/patches/0003-openssl-zlib-ext.patch | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+), 14 deletions(-) delete mode 100644 recipes/ruby/all/patches/0003-openssl-ext.patch create mode 100644 recipes/ruby/all/patches/0003-openssl-zlib-ext.patch diff --git a/recipes/ruby/all/conandata.yml b/recipes/ruby/all/conandata.yml index 4dbd391211d28..1ae63b3ba77ad 100644 --- a/recipes/ruby/all/conandata.yml +++ b/recipes/ruby/all/conandata.yml @@ -5,6 +5,10 @@ sources: patches: "3.1.0": - patch_file: "patches/0001-darwin-includedir.patch" + patch_type: "portability" - patch_file: "patches/0002-remove-fpic.patch" - - patch_file: "patches/0003-openssl-ext.patch" + patch_type: "portability" + - patch_file: "patches/0003-openssl-zlib-ext.patch" + patch_type: "conan" - patch_file: "patches/0004-windows-cflags.patch" + patch_type: "portability" diff --git a/recipes/ruby/all/patches/0003-openssl-ext.patch b/recipes/ruby/all/patches/0003-openssl-ext.patch deleted file mode 100644 index 4ce36eb65a9c1..0000000000000 --- a/recipes/ruby/all/patches/0003-openssl-ext.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb ---- ext/openssl/extconf.rb -+++ ext/openssl/extconf.rb -@@ -45,8 +45,9 @@ - if $mswin || $mingw - # required for static OpenSSL libraries - have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen()) - have_library("crypt32") -+ have_library("advapi32") - end - - return false unless have_header("openssl/ssl.h") - diff --git a/recipes/ruby/all/patches/0003-openssl-zlib-ext.patch b/recipes/ruby/all/patches/0003-openssl-zlib-ext.patch new file mode 100644 index 0000000000000..40b0d3ccd90e7 --- /dev/null +++ b/recipes/ruby/all/patches/0003-openssl-zlib-ext.patch @@ -0,0 +1,37 @@ +diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb +--- ext/openssl/extconf.rb ++++ ext/openssl/extconf.rb +@@ -46,6 +46,7 @@ def find_openssl_library + # required for static OpenSSL libraries + have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen()) + have_library("crypt32") ++ have_library("advapi32") + end + + return false unless have_header("openssl/ssl.h") +@@ -56,9 +57,13 @@ def find_openssl_library + + if $mswin + # OpenSSL >= 1.1.0: libcrypto.lib and libssl.lib. ++ # Potentially with 'd' appended (conan center index) + if have_library("libcrypto", "CRYPTO_malloc") && + have_library("libssl", "SSL_new") + return true ++ elsif have_library("libcryptod", "CRYPTO_malloc") && ++ have_library("libssld", "SSL_new") ++ return true + end + + # OpenSSL <= 1.0.2: libeay32.lib and ssleay32.lib. +diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb +--- ext/zlib/extconf.rb ++++ ext/zlib/extconf.rb +@@ -11,7 +11,7 @@ require 'rbconfig' + dir_config 'zlib' + + libs = $libs +-if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and ++if %w'z zlibstatic zlibstaticd zlib zlibd libz zlib1 zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and + have_header('zlib.h') then + have_zlib = true + else From 581ed330ebcf2f5b653b6ced80dc1bcc08e88655 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Wed, 20 Dec 2023 14:30:56 +0100 Subject: [PATCH 12/31] use PkgConfigDeps - fixes an issue present on master branch cf https://github.com/conan-io/conan-center-index/pull/18338#issuecomment-1864393272 --- recipes/ruby/all/conanfile.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 3cb7dfa525f35..2e24bfecf598e 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -2,8 +2,9 @@ from conan.errors import ConanInvalidConfiguration from conan.tools.apple import is_apple_os, to_apple_arch from conan.tools.build import cross_building +from conan.tools.env import VirtualBuildEnv from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, rm, rmdir -from conan.tools.gnu import Autotools, AutotoolsDeps, AutotoolsToolchain +from conan.tools.gnu import Autotools, PkgConfigDeps, AutotoolsToolchain from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars from conan.tools.scm import Version @@ -68,6 +69,10 @@ def _msvc_optflag(self): def export_sources(self): export_conandata_patches(self) + def build_requirements(self): + if not self.conf.get("tools.gnu:pkg_config", check_type=str): + self.tool_requires("pkgconf/2.1.0") + def config_options(self): if self.settings.os == "Windows": del self.options.fPIC @@ -114,17 +119,11 @@ def source(self): get(self, **self.conan_data["sources"][self.version], strip_root=True) def generate(self): - td = AutotoolsDeps(self) - # remove non-existing frameworks dirs, otherwise clang complains - for m in re.finditer(r'-F(?: |\")([^\r\n\t\f\v\" ]+)\"?', td.vars().get("LDFLAGS")): - if not os.path.exists(m[1]): - td.environment.remove("LDFLAGS", m[0]) - if self.settings.os == "Windows": - if is_msvc(self): - td.environment.append("LIBS", [f"{lib}.lib" for lib in self._windows_system_libs]) - else: - td.environment.append("LDFLAGS", [f"-l{lib}" for lib in self._windows_system_libs]) - td.generate() + venv = VirtualBuildEnv(self) + venv.generate() + + deps = PkgConfigDeps(self) + deps.generate() tc = AutotoolsToolchain(self) From a63e33a3fff780200613209f6d65e8ca08f5a940 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 21 Dec 2023 09:54:10 +0100 Subject: [PATCH 13/31] Use CMakeToolChain to pass variables to cmake in test_package --- recipes/ruby/all/test_package/conanfile.py | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index dc55d277cc5ca..b588083ec99d3 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -4,12 +4,12 @@ from conan import ConanFile from conan.tools.build import can_run -from conan.tools.cmake import CMake, cmake_layout +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" - generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" + generators = "CMakeDeps", "VirtualRunEnv" def requirements(self): self.requires(self.tested_reference_str) @@ -20,19 +20,21 @@ def build_requirements(self): def layout(self): cmake_layout(self) - def build(self): - cmake = CMake(self) + def generate(self): # when --static-linked-ext is used, ruby defines EXTSTATIC as 1 # But when ruby itself is static there's nothing, so: # We define RUBY_STATIC_RUBY when ruby itself is static # We define RUBY_STATIC_LINKED_EXT when the ruby extensions are static (same as EXTSTATIC but clearer) - defs = {} - tested_options = self.dependencies[self.tested_reference_str].options - if not tested_options.shared: - defs["RUBY_STATIC_RUBY"] = 1 - if tested_options.with_static_linked_ext: - defs["RUBY_STATIC_LINKED_EXT"] = 1 - cmake.configure(variables=defs) + # This is only for testing purposes + ruby_opts = self.dependencies[self.tested_reference_str].options + tc = CMakeToolchain(self) + tc.variables["RUBY_STATIC_RUBY"] = not ruby_opts.shared + tc.variables["RUBY_STATIC_LINKED_EXT"] = not ruby_opts.shared and ruby_opts.with_static_linked_ext + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() cmake.build() def _ruby_version(self): From 44dce48d50bdc4b248063793fe174abaf61ae567 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 21 Dec 2023 10:45:00 +0100 Subject: [PATCH 14/31] v1 output contains the command being run, so test with "in" and not equality --- recipes/ruby/all/test_package/conanfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index b588083ec99d3..521df25c5d558 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -56,8 +56,10 @@ def _test_ruby_execute(self): output = StringIO() self.run('ruby -e "puts RUBY_VERSION"', output, env="conanbuild") output_str = str(output.getvalue()).strip() - self.output.info(f'ruby -e "PUTS RUBY_VERSION": {output_str}') - assert output_str == self._ruby_version() + self.output.info(f'ruby -e "puts RUBY_VERSION": "{output_str}"') + assert_ruby_version = self._ruby_version() + self.output.info(f"Expected version: '{assert_ruby_version}'") + assert assert_ruby_version in output_str def test(self): self._test_ruby_executable_version() From 5bd4ff06d7219176df7741a941733c9854e256af Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 21 Dec 2023 10:47:53 +0100 Subject: [PATCH 15/31] Adjust to_apple_arch which apparently takes conanfile --- recipes/ruby/all/conanfile.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 2e24bfecf598e..21bc4b3aad5e1 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -11,7 +11,6 @@ import glob import os -import re required_conan_version = ">=1.53" @@ -156,7 +155,7 @@ def generate(self): tc.configure_args.append(f"--with-opt-dir={sep.join(opt_dirs)}") if cross_building(self) and is_apple_os(self): - apple_arch = to_apple_arch(self.settings.arch) + apple_arch = to_apple_arch(self) if apple_arch: tc.configure_args.append(f"--with-arch={apple_arch}") if is_msvc(self): From 63f190cf338c9659fa8e676ba9f8e83e565edcca Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 21 Dec 2023 12:05:36 +0100 Subject: [PATCH 16/31] Try to explicitly depend on autoconf/2.71 for V2 pipeline failure on mac --- recipes/ruby/all/conanfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 21bc4b3aad5e1..01dde30647461 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -69,6 +69,8 @@ def export_sources(self): export_conandata_patches(self) def build_requirements(self): + if self.settings.os != "Windows": + self.tool_requires("autoconf/2.71") if not self.conf.get("tools.gnu:pkg_config", check_type=str): self.tool_requires("pkgconf/2.1.0") From b35b4222875c0864b32cd23f8ed11ed448843a2f Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 22 Dec 2023 18:35:20 +0100 Subject: [PATCH 17/31] Try with rbs 3.1.0 instead... --- recipes/ruby/all/conanfile.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 01dde30647461..ac496eb58f2cb 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -3,7 +3,7 @@ from conan.tools.apple import is_apple_os, to_apple_arch from conan.tools.build import cross_building from conan.tools.env import VirtualBuildEnv -from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, rm, rmdir +from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, replace_in_file, rm, rmdir from conan.tools.gnu import Autotools, PkgConfigDeps, AutotoolsToolchain from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars @@ -175,8 +175,12 @@ def generate(self): vc = VCVars(self) vc.generate() - def build(self): + def _patch_sources(self): apply_conandata_patches(self) + replace_in_file(self, os.path.join(self.source_folder, "gems", "bundled_gems"), "rbs 2.0.0", "rbs 3.1.0") + + def build(self): + self._patch_sources() autotools = Autotools(self) From cb560cec656197dfe54194106e775142c5aec383 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 22 Dec 2023 19:55:38 +0100 Subject: [PATCH 18/31] try with debug 1.6.3 now... --- recipes/ruby/all/conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index ac496eb58f2cb..73fe03a880090 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -178,6 +178,7 @@ def generate(self): def _patch_sources(self): apply_conandata_patches(self) replace_in_file(self, os.path.join(self.source_folder, "gems", "bundled_gems"), "rbs 2.0.0", "rbs 3.1.0") + replace_in_file(self, os.path.join(self.source_folder, "gems", "bundled_gems"), "debug 1.4.0", "debug 1.6.3") def build(self): self._patch_sources() From b50d916a02fd7c08bf2a59c97f8760b81901d7c7 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 22 Dec 2023 22:04:36 +0100 Subject: [PATCH 19/31] Cross building: pass DESTDIR as arg to make install-local Note: ruby has a `--with-destdir=DESTDIR specify default directory to install` option, maybe I should use that? --- recipes/ruby/all/conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 73fe03a880090..4d9aa075c468c 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -202,8 +202,8 @@ def package(self): autotools = Autotools(self) if cross_building(self): - autotools.make(target="install-local") - autotools.make(target="install-arch") + autotools.make(target="install-local", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) + autotools.make(target="install-arch", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) else: autotools.install() From fe49bed7e1a6b10a7dfd75839584e562ce6ae493 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 22 Jan 2024 23:28:15 +0100 Subject: [PATCH 20/31] remove tool_requires --- recipes/ruby/all/conanfile.py | 1 + recipes/ruby/all/test_package/conanfile.py | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 4d9aa075c468c..542397c963b1e 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -255,3 +255,4 @@ def package_info(self): self.cpp_info.names["cmake_find_package_multi"] = "Ruby" binpath = os.path.join(self.package_folder, "bin") self.env_info.PATH.append(binpath) + self.runenv_info.prepend_path("PATH", os.path.join(self.package_folder, "bin")) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 521df25c5d558..48c500a52771c 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -14,9 +14,6 @@ class TestPackageConan(ConanFile): def requirements(self): self.requires(self.tested_reference_str) - def build_requirements(self): - self.tool_requires(self.tested_reference_str) - def layout(self): cmake_layout(self) @@ -44,7 +41,7 @@ def _ruby_version(self): def _test_ruby_executable_version(self): # test executable output = StringIO() - self.run("ruby --version", output, env="conanbuild") + self.run("ruby --version", output, env="conanrun") output_str = str(output.getvalue()).strip() self.output.info(f"Installed version: {output_str}") assert_ruby_version = f"ruby {self._ruby_version()}" @@ -54,7 +51,7 @@ def _test_ruby_executable_version(self): def _test_ruby_execute(self): # test executable output = StringIO() - self.run('ruby -e "puts RUBY_VERSION"', output, env="conanbuild") + self.run('ruby -e "puts RUBY_VERSION"', output, env="conanrun") output_str = str(output.getvalue()).strip() self.output.info(f'ruby -e "puts RUBY_VERSION": "{output_str}"') assert_ruby_version = self._ruby_version() @@ -62,10 +59,10 @@ def _test_ruby_execute(self): assert assert_ruby_version in output_str def test(self): - self._test_ruby_executable_version() - self._test_ruby_execute() - if can_run(self): + self._test_ruby_executable_version() + self._test_ruby_execute() + # test library bin_path = os.path.join(self.cpp.build.bindirs[0], "bin", "test_package") self.run(bin_path, env="conanrun") From d88e0eb1e8e512175d510c4dee798f54e51cae02 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 03:44:39 +0100 Subject: [PATCH 21/31] Windows adjusts: don't try to use conan libffi --- recipes/ruby/all/conanfile.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 542397c963b1e..85bc5ab12cf8f 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -6,7 +6,7 @@ from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, replace_in_file, rm, rmdir from conan.tools.gnu import Autotools, PkgConfigDeps, AutotoolsToolchain from conan.tools.layout import basic_layout -from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars +from conan.tools.microsoft import check_min_vs, is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path, VCVars from conan.tools.scm import Version import glob @@ -60,10 +60,10 @@ def _windows_system_libs(self): @property def _msvc_optflag(self): - if self.settings.compiler == "Visual Studio" and Version(self.settings.compiler.version) < "14": - return "-O2b2xg-" - else: + if check_min_vs(self, "190", raise_invalid=False): return "-O2sy-" + else: # MSVC < 14 + return "-O2b2xg-" def export_sources(self): export_conandata_patches(self) @@ -90,6 +90,9 @@ def configure(self): # readline isn't supported on Windows del self.options.with_readline + if is_msvc(self): + # conan libffi will not allow linking right now with MSVC + del self.options.with_libffi def requirements(self): self.requires("zlib/1.2.12") @@ -99,7 +102,7 @@ def requirements(self): if self.options.with_libyaml: self.requires("libyaml/0.2.5") - if self.options.with_libffi: + if self.options.get_safe("with_libffi"): self.requires("libffi/3.4.2") if self.options.get_safe("with_readline"): @@ -163,6 +166,9 @@ def generate(self): if is_msvc(self): # this is marked as TODO in https://github.com/conan-io/conan/blob/01f4aecbfe1a49f71f00af8f1b96b9f0174c3aad/conan/tools/gnu/autotoolstoolchain.py#L23 tc.build_type_flags.append(f"-{msvc_runtime_flag(self)}") + + if Version(self.version) < "3.2.0": + tc.configure_args.append("--enable-bundled-libffi") # https://github.com/conan-io/conan/issues/10338 # remove after conan 1.45 if self.settings.build_type in ["Debug", "RelWithDebInfo"]: From 6277fbace3956a2956b7d5fb6a51d3cb1d70db78 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 03:54:39 +0100 Subject: [PATCH 22/31] Escape opt-dir, disable readline, use nmake --- recipes/ruby/all/conanfile.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 85bc5ab12cf8f..fa581e00998f6 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -157,7 +157,7 @@ def generate(self): if opt_dirs: sep = ";" if self.settings.os == "Windows" else ":" - tc.configure_args.append(f"--with-opt-dir={sep.join(opt_dirs)}") + tc.configure_args.append(f'--with-opt-dir="{sep.join(opt_dirs)}"') if cross_building(self) and is_apple_os(self): apple_arch = to_apple_arch(self) @@ -166,15 +166,15 @@ def generate(self): if is_msvc(self): # this is marked as TODO in https://github.com/conan-io/conan/blob/01f4aecbfe1a49f71f00af8f1b96b9f0174c3aad/conan/tools/gnu/autotoolstoolchain.py#L23 tc.build_type_flags.append(f"-{msvc_runtime_flag(self)}") - - if Version(self.version) < "3.2.0": - tc.configure_args.append("--enable-bundled-libffi") # https://github.com/conan-io/conan/issues/10338 # remove after conan 1.45 if self.settings.build_type in ["Debug", "RelWithDebInfo"]: tc.ldflags.append("-debug") tc.build_type_flags = [f if f != "-O2" else self._msvc_optflag for f in tc.build_type_flags] + tc.configure_args.append("--without-ext=+,dbm,gdbm,readline") + if Version(self.version) < "3.2.0": + tc.configure_args.append("--enable-bundled-libffi") tc.generate() if is_msvc(self): @@ -193,21 +193,29 @@ def build(self): build_script_folder = self.source_folder if is_msvc(self): - self.conf["tools.gnu:make_program"] = "nmake" + # self.conf["tools.gnu:make_program"] = "nmake" + # self.conf_info.define("tools.gnu:make_program", "nmake") build_script_folder = os.path.join(build_script_folder, "win32") if "TMP" in os.environ: # workaround for TMP in CCI containing both forward and back slashes os.environ["TMP"] = os.environ["TMP"].replace("/", "\\") autotools.configure(build_script_folder=build_script_folder) - autotools.make() + if is_msvc(self): + self.run("nmake incs") + self.run("nmake extract-extlibs") + self.run("nmake") + else: + autotools.make() def package(self): for file in ["COPYING", "BSDL"]: copy(self, pattern=file, src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) autotools = Autotools(self) - if cross_building(self): + if is_msvc(self): + self.run("nmake install-nodoc") + elif cross_building(self): autotools.make(target="install-local", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) autotools.make(target="install-arch", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) else: From f406535b2446b32877d7c153187771bc5f96f8cd Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 04:11:45 +0100 Subject: [PATCH 23/31] Add patch_description (conan v2) --- recipes/ruby/all/conandata.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recipes/ruby/all/conandata.yml b/recipes/ruby/all/conandata.yml index 1ae63b3ba77ad..a3befbfbb2bdb 100644 --- a/recipes/ruby/all/conandata.yml +++ b/recipes/ruby/all/conandata.yml @@ -5,10 +5,14 @@ sources: patches: "3.1.0": - patch_file: "patches/0001-darwin-includedir.patch" + patch_description: "Remove SDKROOT on macOS" patch_type: "portability" - patch_file: "patches/0002-remove-fpic.patch" + patch_description: "Remove hardcoded fPIC" patch_type: "portability" - patch_file: "patches/0003-openssl-zlib-ext.patch" + patch_description: "Handle naming of zlib and openssl" patch_type: "conan" - patch_file: "patches/0004-windows-cflags.patch" + patch_description: "Define cflags properly on windows" patch_type: "portability" From 25760836ecb860d6c899b71f2ac7c6f356209c19 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 04:15:39 +0100 Subject: [PATCH 24/31] Don't link to conan libyaml on msvc, it fails to link For libffi and libyaml, starting at 3.2.x ruby supports: * Downloading the SOURCES to libyaml / libffi * Configure with --with-libyaml-source-dir / --with-libffi-source-dir * It then builds the libffi / libyaml itself https://bugs.ruby-lang.org/issues/18571 --- recipes/ruby/all/conanfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index fa581e00998f6..f823ba49d11c3 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -93,13 +93,16 @@ def configure(self): if is_msvc(self): # conan libffi will not allow linking right now with MSVC del self.options.with_libffi + # conan LibYAML will not link properly right now with MSVC, so using built-in Psych provided libYAML + del self.options.with_libyaml + def requirements(self): self.requires("zlib/1.2.12") if self.options.with_openssl: self.requires("openssl/1.1.1q") - if self.options.with_libyaml: + if self.options.get_safe("with_libyaml"): self.requires("libyaml/0.2.5") if self.options.get_safe("with_libffi"): From 333c63d7bb423e563b9d4a39fce6a0f243791c2a Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 04:34:01 +0100 Subject: [PATCH 25/31] Pass DESTDIR to nmake --- recipes/ruby/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index f823ba49d11c3..9ac02a8a7585d 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -217,7 +217,7 @@ def package(self): autotools = Autotools(self) if is_msvc(self): - self.run("nmake install-nodoc") + self.run(f"nmake install-nodoc DESTDIR={self.package_folder}") elif cross_building(self): autotools.make(target="install-local", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) autotools.make(target="install-arch", args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) From 219f191a99ed8be064c3b3e49b90e4058be81c7e Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 05:36:05 +0100 Subject: [PATCH 26/31] quote with-opt-dir only on windows --- recipes/ruby/all/conanfile.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 9ac02a8a7585d..6acd0abf970b2 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -159,8 +159,12 @@ def generate(self): opt_dirs.append(root_path) if opt_dirs: - sep = ";" if self.settings.os == "Windows" else ":" - tc.configure_args.append(f'--with-opt-dir="{sep.join(opt_dirs)}"') + if self.settings.os == "Windows": + sep = ";" + tc.configure_args.append(f'--with-opt-dir="{sep.join(opt_dirs)}"') + else: + sep = ":" + tc.configure_args.append(f'--with-opt-dir={sep.join(opt_dirs)}') if cross_building(self) and is_apple_os(self): apple_arch = to_apple_arch(self) From 445df2afedec2e124e496077dca714a4ff1cb04c Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 05:36:36 +0100 Subject: [PATCH 27/31] Adjust test_package --- recipes/ruby/all/test_package/CMakeLists.txt | 4 ---- recipes/ruby/all/test_package/conanfile.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/recipes/ruby/all/test_package/CMakeLists.txt b/recipes/ruby/all/test_package/CMakeLists.txt index 55e2e39746e22..ba39afa4ee59b 100644 --- a/recipes/ruby/all/test_package/CMakeLists.txt +++ b/recipes/ruby/all/test_package/CMakeLists.txt @@ -18,7 +18,3 @@ endif() if (RUBY_STATIC_LINKED_EXT) target_compile_definitions(${PROJECT_NAME} PRIVATE RUBY_STATIC_LINKED_EXT) endif() -set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin) -set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}/bin) -set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_BINARY_DIR}/bin) -set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin) diff --git a/recipes/ruby/all/test_package/conanfile.py b/recipes/ruby/all/test_package/conanfile.py index 48c500a52771c..8323b0049275e 100644 --- a/recipes/ruby/all/test_package/conanfile.py +++ b/recipes/ruby/all/test_package/conanfile.py @@ -64,5 +64,5 @@ def test(self): self._test_ruby_execute() # test library - bin_path = os.path.join(self.cpp.build.bindirs[0], "bin", "test_package") + bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package") self.run(bin_path, env="conanrun") From ee3a932160f97621f124766ea18e17f0a8ed81ee Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 12:44:16 +0100 Subject: [PATCH 28/31] nmake extract-extlibs requires a base ruby available, which CI windows doesn't have --- recipes/ruby/all/conanfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 6acd0abf970b2..3ae956f1393ea 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -11,6 +11,7 @@ import glob import os +import shutil required_conan_version = ">=1.53" @@ -210,7 +211,8 @@ def build(self): autotools.configure(build_script_folder=build_script_folder) if is_msvc(self): self.run("nmake incs") - self.run("nmake extract-extlibs") + if shutil.which("ruby"): + self.run("nmake extract-extlibs") self.run("nmake") else: autotools.make() From c98681081519db023c8261a7e07e1b7d668a1695 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 12:44:59 +0100 Subject: [PATCH 29/31] Actually just assumes that the current libffi bundled in source is up to date, and don't do extract-extlibs --- recipes/ruby/all/conanfile.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index 3ae956f1393ea..a13d730019018 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -11,7 +11,6 @@ import glob import os -import shutil required_conan_version = ">=1.53" @@ -211,8 +210,6 @@ def build(self): autotools.configure(build_script_folder=build_script_folder) if is_msvc(self): self.run("nmake incs") - if shutil.which("ruby"): - self.run("nmake extract-extlibs") self.run("nmake") else: autotools.make() From 0178690a687783997268719fd8f2fa455f798943 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Tue, 23 Jan 2024 21:09:31 +0100 Subject: [PATCH 30/31] Use fix_apple_shared_install_name to shush KB-H077? > post_package(): WARN: [APPLE RELOCATABLE SHARED LIBS (KB-H077)] install_name dir of these shared libs is not @rpath: libruby.3.1.dylib, libruby.dylib https://github.com/conan-io/conan-center-index/pull/18338#issuecomment-1906155741 --- recipes/ruby/all/conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/ruby/all/conanfile.py b/recipes/ruby/all/conanfile.py index a13d730019018..5d17a27231c60 100644 --- a/recipes/ruby/all/conanfile.py +++ b/recipes/ruby/all/conanfile.py @@ -1,6 +1,6 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration -from conan.tools.apple import is_apple_os, to_apple_arch +from conan.tools.apple import is_apple_os, fix_apple_shared_install_name, to_apple_arch from conan.tools.build import cross_building from conan.tools.env import VirtualBuildEnv from conan.tools.files import apply_conandata_patches, collect_libs, copy, export_conandata_patches, get, replace_in_file, rm, rmdir @@ -230,6 +230,7 @@ def package(self): rmdir(self, os.path.join(self.package_folder, "share")) rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) rm(self, pattern="*.pdb", folder=os.path.join(self.package_folder, "lib")) + fix_apple_shared_install_name(self) # install the enc/*.a / ext/*.a libraries if not self.options.shared and self.options.with_static_linked_ext: From 7ddb85e1c871647d4ba8d10bdfbb59f2fc6cbde3 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Fri, 2 Feb 2024 08:56:50 +0100 Subject: [PATCH 31/31] Backport --add-gmp-dir in an attempt to fix miniruby not loading gmp lib During the build, miniruby is built, then it is actually used to build the extension libs. The c3i v2 runner on macOS is failing ``` linking miniruby dyld[16179]: Library not loaded: @rpath/libgmp.10.dylib Referenced from: /Users/jenkins/w/prod-v2/bsr@2/80054/defbf/p/b/ruby1af0f3d020f64/b/build-release/miniruby Reason: tried: '/usr/local/lib/libgmp.10.dylib' (no such file), '/usr/lib/libgmp.10.dylib' (no such file, not in dyld cache) make: *** [exe/ruby] Abort trap: 6 make: *** Deleting file `exe/ruby' ``` --- recipes/ruby/all/conandata.yml | 4 +++ ...0005-backport-add-with-gmp-dir-3.1.0.patch | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 recipes/ruby/all/patches/0005-backport-add-with-gmp-dir-3.1.0.patch diff --git a/recipes/ruby/all/conandata.yml b/recipes/ruby/all/conandata.yml index a3befbfbb2bdb..2dcd99b10ac8e 100644 --- a/recipes/ruby/all/conandata.yml +++ b/recipes/ruby/all/conandata.yml @@ -16,3 +16,7 @@ patches: - patch_file: "patches/0004-windows-cflags.patch" patch_description: "Define cflags properly on windows" patch_type: "portability" + - patch_file: "patches/0005-backport-add-with-gmp-dir-3.1.0.patch" + patch_description: "backport add --with-gmp-dir which was added only in 3.2.0" + patch_type: "backport" + patch_source: "https://github.com/ruby/ruby/commit/f512df73986c74e2f4bd65ca642879a0618da213" diff --git a/recipes/ruby/all/patches/0005-backport-add-with-gmp-dir-3.1.0.patch b/recipes/ruby/all/patches/0005-backport-add-with-gmp-dir-3.1.0.patch new file mode 100644 index 0000000000000..f71205ece9743 --- /dev/null +++ b/recipes/ruby/all/patches/0005-backport-add-with-gmp-dir-3.1.0.patch @@ -0,0 +1,35 @@ +Subject: backport add --with-gmp-dir + +backport https://github.com/ruby/ruby/pull/6366 + +diff --git a/configure.ac b/configure.ac +--- configure.ac ++++ configure.ac +@@ -910,6 +910,15 @@ AC_ARG_WITH(opt-dir, + OPT_DIR="$withval" + ], [OPT_DIR=]) + ++AC_ARG_WITH([gmp-dir], ++ AS_HELP_STRING([--with-gmp-dir=DIR], ++ [specify the prefix directory where gmp is installed]), ++ [OPT_DIR="${OPT_DIR:+$OPT_DIR$PATH_SEPARATOR}$withval"], []) ++AC_ARG_WITH([gmp], ++ [AS_HELP_STRING([--without-gmp], ++ [disable GNU GMP to accelerate Bignum operations])], ++ [], [with_gmp=yes]) ++ + test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $ARCH_FLAG\"" + test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\"" + } +@@ -1309,11 +1318,6 @@ AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [ + ]) + RUBY_UNIVERSAL_CHECK_HEADER([x86_64, i386], x86intrin.h) + +-AC_ARG_WITH([gmp], +- [AS_HELP_STRING([--without-gmp], +- [disable GNU GMP to accelerate Bignum operations])], +- [], +- [with_gmp=yes]) + AS_IF([test "x$with_gmp" != xno], + [AC_CHECK_HEADERS(gmp.h) + AS_IF([test "x$ac_cv_header_gmp_h" != xno],