Skip to content

Commit

Permalink
(#13355) libffi: Support Conan V2
Browse files Browse the repository at this point in the history
* Added Conan v2 support

Based on this template:
https://github.com/conan-io/conan-center-index/tree/master/docs/package_templates/autotools_package

Contribute to CURA-9628

* catch ValueError instead of broad Exception catch

Contributes to CURA-9628

* Validating not needed in this recipe

Contributes to CURA-9628

* Clean-up various path references

Contributes to CURA-9628

* Use modern apple rpath fix

Contributes to CURA-9628

* Reapplied patches again

Contributes to CURA-9628

* convert Path to str before passing to unix_path

Contributes to CURA-9628

* Removed clang exception in generate

Contributes to CURA-9628

* Use user_info.ar_lib as a workaround

Should be reverted once #12898
has been merged

Contribute to CURA-9628 and CURA-9575

* disable multi os directory when compiling with apple-clang

Contributes to CURA-9628

* Use conf for AR variable

Contributes to CURA-9628

* Slight clean up

* Evaluate ar-lib path

* Update recipes/libffi/all/conanfile.py

Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com>

* Move DLL's to the bin directory

* Rename source folder to src

* Small fixes

* Fix renaming DLL's

* Make bin directory

* Be sure to set DISABLE_FFI_CALL properly

* Remove stuff AutotoolsToolchain should set

* Clean up compiler wrapper

* Move VirtualBuildEnv before MSVC settings

* Add missing generate method for toolchain

* Use provided compile wrapper and add missing defines

* Set build and host

* Add architecture flags

* Pass architecture flag to compiler wrapper

* Fix for Clang on Windows

* Use gnu-config

* Fix copy-paste

* Use cygwin triplet

* Use the VCVars generator

* Revert "Use cygwin triplet"

This reverts commit 0ef94c6.

* Revert "Use gnu-config"

This reverts commit 79d2f4e.

* Fix wrapper

* Define the assembler in the wrapper script

* Remove VCVars

* Use the toolchain's environment

* Fix Windows to use wrapper script

* Align with updated autotools template

* Always define FFI_BUILDING

* Don't define FFI_DEBUG

* Try patching version 3.2.1

* Revert "Try patching version 3.2.1"

This reverts commit f15d3e4.

* Drop version 3.2.1

This is no longer building and I don't know why.
It's also from 2014, so hopefully it's okay to drop.

* Clean up

Co-authored-by: Jelle Spijker <j.spijker@ultimaker.com>
Co-authored-by: j.spijker@ultimaker.com <jelle spijker>
Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 24, 2022
1 parent 35905b3 commit 0bab4d3
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 562 deletions.
52 changes: 12 additions & 40 deletions recipes/libffi/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,19 @@ sources:
"3.3":
url: "https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz"
sha256: "72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056"
"3.2.1":
url: "https://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz"
sha256: "d06ebb8e1d9a22d19e38d63fdb83954253f39bedc5d46232a05645685722ca37"
patches:
"3.4.3":
- base_path: "source_subfolder"
patch_file: "patches/0002-3.4.3-fix-libtool-path.patch"
- base_path: "source_subfolder"
patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- base_path: "source_subfolder"
patch_file: "patches/0005-3.4.3-do-not-install-libraries-to-arch-dependent-directories.patch"
- base_path: "source_subfolder"
patch_file: "patches/0006-3.4.3-library-no-version-suffix.patch"
- patch_file: "patches/0002-3.4.3-fix-libtool-path.patch"
- patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- patch_file: "patches/0005-3.4.3-do-not-install-libraries-to-arch-dependent-directories.patch"
- patch_file: "patches/0006-3.4.3-library-no-version-suffix.patch"
"3.4.2":
- base_path: "source_subfolder"
patch_file: "patches/0002-3.4.2-fix-libtool-path.patch"
- base_path: "source_subfolder"
patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- base_path: "source_subfolder"
patch_file: "patches/0005-3.4.2-do-not-install-libraries-to-arch-dependent-directories.patch"
- base_path: "source_subfolder"
patch_file: "patches/0006-3.4.2-library-no-version-suffix.patch"
- patch_file: "patches/0002-3.4.2-fix-libtool-path.patch"
- patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- patch_file: "patches/0005-3.4.2-do-not-install-libraries-to-arch-dependent-directories.patch"
- patch_file: "patches/0006-3.4.2-library-no-version-suffix.patch"
"3.3":
- base_path: "source_subfolder"
patch_file: "patches/0002-3.3-fix-libtool-path.patch"
- base_path: "source_subfolder"
patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- base_path: "source_subfolder"
patch_file: "patches/0005-3.3-do-not-install-libraries-to-arch-dependent-directories.patch"
- base_path: "source_subfolder"
patch_file: "patches/0006-3.3-library-no-version-suffix.patch"
"3.2.1":
- base_path: "source_subfolder"
patch_file: "patches/0001-3.2.1-add-support-windows-dll.patch"
- base_path: "source_subfolder"
patch_file: "patches/0002-3.2.1-fix-libtool-path.patch"
- base_path: "source_subfolder"
patch_file: "patches/0003-3.2.1-fix-win64-assembly.patch"
- base_path: "source_subfolder"
patch_file: "patches/0004-3.2.1-fix-complex-type-msvc.patch"
- base_path: "source_subfolder"
patch_file: "patches/0005-3.2.1-do-not-install-libraries-to-arch-dependent-directories.patch"
- base_path: "source_subfolder"
patch_file: "patches/0006-3.2.1-library-no-version-suffix.patch"
- patch_file: "patches/0002-3.3-fix-libtool-path.patch"
- patch_file: "patches/0004-3.3-fix-complex-type-msvc.patch"
- patch_file: "patches/0005-3.3-do-not-install-libraries-to-arch-dependent-directories.patch"
- patch_file: "patches/0006-3.3-library-no-version-suffix.patch"
266 changes: 133 additions & 133 deletions recipes/libffi/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
from conan.tools.microsoft import msvc_runtime_flag
from conans import ConanFile, tools, AutoToolsBuildEnvironment
import contextlib
from conan import ConanFile
from conan.tools.apple import fix_apple_shared_install_name
from conan.tools.env import VirtualBuildEnv
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, mkdir, replace_in_file, rm, rmdir
from conan.tools.gnu import Autotools, AutotoolsToolchain
from conan.tools.layout import basic_layout
from conan.tools.microsoft import is_msvc, is_msvc_static_runtime, msvc_runtime_flag, unix_path
from conan.tools.scm import Version
import glob
import os
import shutil

required_conan_version = ">=1.36"
required_conan_version = ">=1.52.0"


class LibffiConan(ConanFile):
name = "libffi"
description = "A portable, high level programming interface to various calling conventions"
topics = ("libffi", "runtime", "foreign-function-interface", "runtime-library")
license = "MIT"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://sourceware.org/libffi/"
license = "MIT"

topics = ("runtime", "foreign-function-interface", "runtime-library")
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
Expand All @@ -25,161 +30,156 @@ class LibffiConan(ConanFile):
"fPIC": True,
}

_autotools = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _is_msvc(self):
return str(self.settings.compiler) in ["Visual Studio", "msvc"]

@property
def _settings_build(self):
# TODO: Remove for Conan v2
return getattr(self, "settings_build", self.settings)

@property
def _user_info_build(self):
return getattr(self, "user_info_build", self.deps_user_info)

def export_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
self.copy(patch["patch_file"])
export_conandata_patches(self)

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.settings.compiler.libcxx
del self.settings.compiler.cppstd
try:
del self.options.fPIC
except Exception:
pass
try:
del self.settings.compiler.libcxx
except Exception:
pass
try:
del self.settings.compiler.cppstd
except Exception:
pass

def layout(self):
basic_layout(self, src_folder="src")

def build_requirements(self):
if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"):
self.build_requires("msys2/cci.latest")
self.build_requires("gnu-config/cci.20201022")
if self._settings_build.os == "Windows":
self.win_bash = True
if not self.conf.get("tools.microsoft.bash:path", default=False, check_type=str):
self.tool_requires("msys2/cci.latest")
if is_msvc(self):
self.tool_requires("automake/1.16.5")

def source(self):
tools.get(**self.conan_data["sources"][self.version],
destination=self._source_subfolder, strip_root=True)

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
# Generate rpath friendly shared lib on macOS
configure_path = os.path.join(self._source_subfolder, "configure")
tools.replace_in_file(configure_path, "-install_name \\$rpath/", "-install_name @rpath/")

if tools.Version(self.version) < "3.3":
if self.settings.compiler == "clang" and tools.Version(str(self.settings.compiler.version)) >= 7.0:
# https://android.googlesource.com/platform/external/libffi/+/ca22c3cb49a8cca299828c5ffad6fcfa76fdfa77
sysv_s_src = os.path.join(self._source_subfolder, "src", "arm", "sysv.S")
tools.replace_in_file(sysv_s_src, "fldmiad", "vldmia")
tools.replace_in_file(sysv_s_src, "fstmiad", "vstmia")
tools.replace_in_file(sysv_s_src, "fstmfdd\tsp!,", "vpush")
get(self, **self.conan_data["sources"][self.version],
destination=self.source_folder, strip_root=True)

def generate(self):
virtual_build_env = VirtualBuildEnv(self)
virtual_build_env.generate()

# https://android.googlesource.com/platform/external/libffi/+/7748bd0e4a8f7d7c67b2867a3afdd92420e95a9f
tools.replace_in_file(sysv_s_src, "stmeqia", "stmiaeq")

@contextlib.contextmanager
def _build_context(self):
extra_env_vars = {}
if tools.os_info.is_windows and (self._is_msvc or self.settings.compiler == "clang") :
msvcc = tools.unix_path(os.path.join(self.source_folder, self._source_subfolder, "msvcc.sh"))
msvcc_args = []
if self._is_msvc:
if self.settings.arch == "x86_64":
msvcc_args.append("-m64")
elif self.settings.arch == "x86":
msvcc_args.append("-m32")
elif self.settings.compiler == "clang":
msvcc_args.append("-clang-cl")

if msvcc_args:
msvcc = "{} {}".format(msvcc, " ".join(msvcc_args))
extra_env_vars.update(tools.vcvars_dict(self.settings))
extra_env_vars.update({
"INSTALL": tools.unix_path(os.path.join(self.source_folder, self._source_subfolder, "install-sh")),
"LIBTOOL": tools.unix_path(os.path.join(self.source_folder, self._source_subfolder, "ltmain.sh")),
"CC": msvcc,
"CXX": msvcc,
"LD": "link",
"CPP": "cl -nologo -EP",
"CXXCPP": "cl -nologo -EP",
})
with tools.environment_append(extra_env_vars):
yield

def _configure_autotools(self):
if self._autotools:
return self._autotools
self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows)
yes_no = lambda v: "yes" if v else "no"
config_args = [
"--enable-debug={}".format(yes_no(self.settings.build_type == "Debug")),
"--enable-shared={}".format(yes_no(self.options.shared)),
"--enable-static={}".format(yes_no(not self.options.shared)),
]
self._autotools.defines.append("FFI_BUILDING")
tc = AutotoolsToolchain(self)
tc.configure_args.extend([
f"--enable-debug={yes_no(self.settings.build_type == 'Debug')}",
"--enable-builddir=no",
"--enable-docs=no",
])

if self._settings_build.compiler == "apple-clang":
tc.configure_args.append("--disable-multi-os-directory")

tc.extra_defines.append("FFI_BUILDING")
if self.options.shared:
self._autotools.defines.append("FFI_BUILDING_DLL")
if self._is_msvc:
if "MT" in msvc_runtime_flag(self):
self._autotools.defines.append("USE_STATIC_RTL")
if "d" in msvc_runtime_flag(self):
self._autotools.defines.append("USE_DEBUG_RTL")
build = None
host = None
if self._is_msvc:
tc.extra_defines.append("FFI_BUILDING_DLL")

env = tc.environment()
if self._settings_build.os == "Windows" and (is_msvc(self) or self.settings.compiler == "clang"):
build = "{}-{}-{}".format(
"x86_64" if self._settings_build.arch == "x86_64" else "i686",
"pc" if self._settings_build.arch == "x86" else "w64",
"cygwin")
"pc" if self._settings_build.arch == "x86" else "win64",
"mingw64")
host = "{}-{}-{}".format(
"x86_64" if self.settings.arch == "x86_64" else "i686",
"pc" if self.settings.arch == "x86" else "w64",
"cygwin")
else:
if self._autotools.host and "x86-" in self._autotools.host:
self._autotools.host = self._autotools.host.replace("x86", "i686")
self._autotools.configure(args=config_args, configure_dir=self._source_subfolder, build=build, host=host)
return self._autotools
"pc" if self.settings.arch == "x86" else "win64",
"mingw64")
tc.configure_args.extend([
f"--build={build}",
f"--host={host}",
])

if (self.settings.compiler == "Visual Studio" and Version(self.settings.compiler.version) >= "12") or \
(self.settings.compiler == "msvc" and Version(self.settings.compiler.version) >= "180"):
tc.extra_cflags.append("-FS")

if is_msvc_static_runtime(self):
tc.extra_defines.append("USE_STATIC_RTL")
if "d" in msvc_runtime_flag(self):
tc.extra_defines.append("USE_DEBUG_RTL")

architecture_flag = ""
if is_msvc(self):
if self.settings.arch == "x86_64":
architecture_flag = "-m64"
elif self.settings.arch == "x86":
architecture_flag = "-m32"
elif self.settings.compiler == "clang":
architecture_flag = "-clang-cl"

compile_wrapper = unix_path(self, os.path.join(self.source_folder, "msvcc.sh"))
if architecture_flag:
compile_wrapper = f"{compile_wrapper} {architecture_flag}"
# FIXME: Use the conf once https://github.com/conan-io/conan-center-index/pull/12898 is merged
# env.define("AR", f"{unix_path(self, self.conf.get('tools.automake:ar-lib'))}")
[version_major, version_minor, _] = self.dependencies.direct_build['automake'].ref.version.split(".", 2)
automake_version = f"{version_major}.{version_minor}"
ar_wrapper = unix_path(self, os.path.join(self.dependencies.direct_build['automake'].cpp_info.resdirs[0], f"automake-{automake_version}", "ar-lib"))
env.define("CC", f"{compile_wrapper}")
env.define("CXX", f"{compile_wrapper}")
env.define("LD", "link -nologo")
env.define("AR", f"{ar_wrapper} \"lib -nologo\"")
env.define("NM", "dumpbin -symbols")
env.define("OBJDUMP", ":")
env.define("RANLIB", ":")
env.define("STRIP", ":")
env.define("CXXCPP", "cl -nologo -EP")
env.define("CPP", "cl -nologo -EP")
env.define("LIBTOOL", unix_path(self, os.path.join(self.source_folder, "ltmain.sh")))
env.define("INSTALL", unix_path(self, os.path.join(self.source_folder, "install-sh")))
tc.generate(env=env)

def _patch_source(self):
apply_conandata_patches(self)

if Version(self.version) < "3.3":
if self.settings.compiler == "clang" and Version(str(self.settings.compiler.version)) >= 7.0:
# https://android.googlesource.com/platform/external/libffi/+/ca22c3cb49a8cca299828c5ffad6fcfa76fdfa77
sysv_s_src = os.path.join(self.source_folder, "src", "arm", "sysv.S")
replace_in_file(self, sysv_s_src, "fldmiad", "vldmia")
replace_in_file(self, sysv_s_src, "fstmiad", "vstmia")
replace_in_file(self, sysv_s_src, "fstmfdd\tsp!,", "vpush")

# https://android.googlesource.com/platform/external/libffi/+/7748bd0e4a8f7d7c67b2867a3afdd92420e95a9f
replace_in_file(self, sysv_s_src, "stmeqia", "stmiaeq")

def build(self):
self._patch_sources()
shutil.copy(self._user_info_build["gnu-config"].CONFIG_SUB,
os.path.join(self._source_subfolder, "config.sub"))
shutil.copy(self._user_info_build["gnu-config"].CONFIG_GUESS,
os.path.join(self._source_subfolder, "config.guess"))

with self._build_context():
autotools = self._configure_autotools()
autotools.make()
if tools.get_env("CONAN_RUN_TESTS", False):
autotools.make(target="check")
self._patch_source()
autotools = Autotools(self)
autotools.configure()
autotools.make()

def package(self):
self.copy("LICENSE", src=self._source_subfolder, dst="licenses")
if self._is_msvc:
if self.options.shared:
self.copy("libffi.dll", src=".libs", dst="bin")
self.copy("libffi.lib", src=".libs", dst="lib")
self.copy("*.h", src="include", dst="include")
else:
with self._build_context():
autotools = self._configure_autotools()
autotools.install()

tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))
tools.rmdir(os.path.join(self.package_folder, "share"))
tools.remove_files_by_mask(os.path.join(self.package_folder, "lib"), "*.la")
autotools = Autotools(self)
autotools.install(args=[f"DESTDIR={unix_path(self, self.package_folder)}"]) # Need to specify the `DESTDIR` as a Unix path, aware of the subsystem
fix_apple_shared_install_name(self)
mkdir(self, os.path.join(self.package_folder, "bin"))
for dll in glob.glob(os.path.join(self.package_folder, "lib", "*.dll")):
shutil.move(dll, os.path.join(self.package_folder, "bin"))
copy(self, "LICENSE", self.source_folder, os.path.join(self.package_folder, "licenses"))
rm(self, "*.la", os.path.join(self.package_folder, "lib"), recursive=True)
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "share"))

def package_info(self):
self.cpp_info.libs = ["{}ffi".format("lib" if is_msvc(self) else "")]
self.cpp_info.set_property("pkg_config_name", "libffi")
self.cpp_info.libs = ["{}ffi".format("lib" if self._is_msvc else "")]
if not self.options.shared:
self.cpp_info.defines = ["FFI_BUILDING"]

Loading

0 comments on commit 0bab4d3

Please sign in to comment.