Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

jemalloc: Revise the recipe to support Conan v2 #17722

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c714ded
jemalloc: Make the recipe compatible with Conan 2.x.
0xFireWolf May 25, 2023
3acda58
jemalloc: Add the patch that adds support for Visual Studio 2019 and …
0xFireWolf May 25, 2023
6082840
jemalloc: Revise the implementation of `validate()`.
0xFireWolf May 25, 2023
a2e5f0f
jemalloc: Define the env variable `CC` if jemalloc is compiled by MSVC.
0xFireWolf May 25, 2023
ace1cb3
jemalloc: Fix the typo.
0xFireWolf May 25, 2023
08169ef
jemalloc: Patch `configure.ac` to add the missing description in `AC_…
0xFireWolf May 25, 2023
0883517
jemalloc: Add `automake` to the build requirements.
0xFireWolf May 25, 2023
e988cd2
jemalloc: Remove the patch that adds the solution files of MSVC 2019 …
0xFireWolf May 27, 2023
3adcec1
jemalloc: Do not check whether the math library exists when jemalloc …
0xFireWolf May 27, 2023
2af2f2d
jemalloc: Remove deprecated functions that set the arguments for Auto…
0xFireWolf May 27, 2023
021f9e6
jemalloc: Revise the function that computes the name of the library a…
0xFireWolf May 27, 2023
6f070ba
jemalloc: Add the patch file that adds the missing description in `AC…
0xFireWolf May 27, 2023
ad7ab69
jemalloc: Remove the function that patches the file `configure.ac`.
0xFireWolf May 27, 2023
5c5fd0d
jemalloc: Remove deprecated implementation of `package()` and `packag…
0xFireWolf May 27, 2023
5ace41d
jemalloc: Copy MSVC compatible headers to the package folder.
0xFireWolf May 27, 2023
b4e319f
jemalloc: Remove the old implementation of `_library_name()`.
0xFireWolf May 27, 2023
3721b96
jemalloc: Use the helper `is_msvc()` instead of checking the compiler…
0xFireWolf May 27, 2023
ebb02d5
jemalloc: Remove the old implementation of `build()`.
0xFireWolf May 27, 2023
16d70cd
jemalloc: Remove the deprecated function `_msvc_build_type()`.
0xFireWolf May 27, 2023
fa03bc1
jemalloc: No need to call `autoreconf`.
0xFireWolf May 27, 2023
416e3fa
jemalloc: Add the missing CXX flags for MSVC.
0xFireWolf May 27, 2023
7bdc18c
jemalloc: Support for Apple Silicon Macs is only available as of 5.3.0.
0xFireWolf May 27, 2023
6c4056c
jemalloc: Remove unneeded `_patch_sources()` function.
0xFireWolf May 27, 2023
f68273d
jemalloc: Fix the linter warnings.
0xFireWolf May 27, 2023
e0aa5ec
jemalloc: No need to set the configuration arguments `--enable-shared…
0xFireWolf Jun 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions recipes/jemalloc/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,14 @@ sources:
patches:
"5.2.1":
- patch_file: "patches/0001-clang12-dont-declare-system-functions-as-nothrow.patch"
patch_description: "Remove nothrow from system function declarations on macOS and FreeBSD."
patch_type: "backport"
"5.3.0":
- patch_file: "patches/0002-add-missing-ac-define-description.patch"
patch_description: "Patch configure.ac to add the missing description in AC_DEFINE."
patch_type: "backport"
patch_source: "https://github.com/jemalloc/jemalloc/pull/2396"
- patch_file: "patches/0003-add-missing-cpp-flags-for-windows.patch"
patch_description: "Add the missing compiler flags for MSVC on Windows."
patch_type: "backport"
patch_source: "https://github.com/jemalloc/jemalloc/issues/2283"
237 changes: 97 additions & 140 deletions recipes/jemalloc/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
from conan import ConanFile
from conans import AutoToolsBuildEnvironment, MSBuild
from conan.errors import ConanInvalidConfiguration
from conan.tools.scm import Version
from conans import tools as tools_legacy
from conan.tools.files import apply_conandata_patches, get, rename, replace_in_file
from conan.tools.env import VirtualBuildEnv
from conan.tools.gnu import Autotools, AutotoolsToolchain
from conan.tools.layout import basic_layout
from conan.tools.files import export_conandata_patches, apply_conandata_patches, get, copy, rename
from conan.tools.microsoft import check_min_vs, is_msvc, is_msvc_static_runtime
from conan.tools.scm import Version
import os
import shutil
import string

required_conan_version = ">=1.51.3"
required_conan_version = ">=1.54.0"


class JemallocConan(ConanFile):
name = "jemalloc"
description = "jemalloc is a general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support."
url = "https://github.com/conan-io/conan-center-index"
license = "BSD-2-Clause"
homepage = "http://jemalloc.net/"
homepage = "https://jemalloc.net/"
topics = ("conan", "jemalloc", "malloc", "free")
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"prefix": "ANY",
"prefix": ["ANY"],
"enable_cxx": [True, False],
"enable_fill": [True, False],
"enable_xmalloc": [True, False],
Expand All @@ -49,61 +50,83 @@ class JemallocConan(ConanFile):
"enable_libdl": True,
"enable_prof": False,
}
exports_sources = ["patches/**"]

_autotools = None
@property
def _settings_build(self):
return getattr(self, "settings_build", self.settings)

@property
def _library_name(self):
libname = "jemalloc"
if self.settings.os == "Windows":
if not self.options.shared:
libname += "_s"
else:
if not self.options.shared and self.options.fPIC:
libname += "_pic"
return libname

def export_sources(self):
export_conandata_patches(self)

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

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

def validate(self):
if self.options.enable_cxx and \
self.settings.compiler.get_safe("libcxx") == "libc++" and \
self.settings.compiler == "clang" and \
Version(self.settings.compiler.version) < "10":
raise ConanInvalidConfiguration("clang and libc++ version {} (< 10) is missing a mutex implementation".format(self.settings.compiler.version))
if self.settings.compiler == "Visual Studio" and \
self.options.shared and \
"MT" in self.settings.compiler.runtime:
raise ConanInvalidConfiguration("Visual Studio build for shared library with MT runtime is not supported")
if self.settings.compiler == "Visual Studio" and self.settings.compiler.version != "15":
# https://github.com/jemalloc/jemalloc/issues/1703
raise ConanInvalidConfiguration("Only Visual Studio 15 2017 is supported. Please fix this if other versions are supported")
if self.settings.build_type not in ("Release", "Debug", None):
raise ConanInvalidConfiguration("Only Release and Debug build_types are supported")
if self.settings.compiler == "Visual Studio" and self.settings.arch not in ("x86_64", "x86"):
raise ConanInvalidConfiguration("Unsupported arch")
if self.settings.compiler == "clang" and Version(self.settings.compiler.version) <= "3.9":
raise ConanInvalidConfiguration("Unsupported compiler version")
if self.settings.os == "Macos" and self.settings.arch not in ("x86_64", "x86"):
raise ConanInvalidConfiguration("Unsupported arch")
self.settings.rm_safe("compiler.cppstd")
self.settings.rm_safe("compiler.libcxx")

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

@property
def _settings_build(self):
return getattr(self, "settings_build", self.settings)

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

def source(self):
get(self, **self.conan_data["sources"][self.version], destination=self.source_folder, strip_root=True)
def validate(self):
# 1. MSVC specific checks
if is_msvc(self):
# The upstream repository provides solution files for Visual Studio 2015, 2017, 2019 and 2022,
# but the 2015 solution does not work properly due to unresolved external symbols:
# `test_hooks_libc_hook` and `test_hooks_arena_new_hook`
check_min_vs(self, "191")
# Building the shared library with a static MSVC runtime is not supported
if self.options.shared and is_msvc_static_runtime(self):
raise ConanInvalidConfiguration("Building the shared library with MT runtime is not supported.")
# Only x86-64 and x86 are supported
if self.settings.arch not in ["x86_64", "x86"]:
raise ConanInvalidConfiguration(f"{self.settings.arch} is not supported.")
# 2. Clang specific checks
if self.settings.compiler == "clang":
if Version(self.settings.compiler.version) <= "3.9":
raise ConanInvalidConfiguration("Clang 3.9 or earlier is not supported.")
if self.options.enable_cxx and self.settings.compiler.get_safe("libcxx") == "libc++" and \
Version(self.settings.compiler.version) < "10":
raise ConanInvalidConfiguration("Clang 9 or earlier with libc++ is not supported due to the missing mutex implementation.")
# 3. Verify the build type
if self.settings.build_type not in ("Release", "Debug", None):
raise ConanInvalidConfiguration("Only Release and Debug builds are supported.")
# 4: Apple Silicon specific checks
if self.settings.os == "Macos" and self.settings.arch == "armv8":
if Version(self.version) < "5.3.0":
raise ConanInvalidConfiguration("Support for Apple Silicon is only available as of 5.3.0.")

@property
def _autotools_args(self):
conf_args = [
"--with-jemalloc-prefix={}".format(self.options.prefix),
def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
env = VirtualBuildEnv(self)
env.generate()
tc = AutotoolsToolchain(self)
tc.configure_args.extend([
f"--with-jemalloc-prefix={self.options.prefix}",
"--enable-debug" if self.settings.build_type == "Debug" else "--disable-debug",
"--enable-cxx" if self.options.enable_cxx else "--disable-cxx",
"--enable-fill" if self.options.enable_fill else "--disable-fill",
Expand All @@ -114,111 +137,45 @@ def _autotools_args(self):
"--enable-log" if self.options.enable_debug_logging else "--disable-log",
"--enable-initial-exec-tls" if self.options.enable_initial_exec_tls else "--disable-initial-exec-tls",
"--enable-libdl" if self.options.enable_libdl else "--disable-libdl",
]
])
if self.options.enable_prof:
conf_args.append("--enable-prof")
if self.options.shared:
conf_args.extend(["--enable-shared", "--disable-static"])
else:
conf_args.extend(["--disable-shared", "--enable-static"])
return conf_args

def _configure_autotools(self):
if self._autotools:
return self._autotools
self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools_legacy.os_info.is_windows)
self._autotools.configure(args=self._autotools_args, configure_dir=self.source_folder)
return self._autotools

@property
def _msvc_build_type(self):
build_type = str(self.settings.build_type) or "Release"
if not self.options.shared:
build_type += "-static"
return build_type

def _patch_sources(self):
if self.settings.os == "Windows":
makefile_in = os.path.join(self.source_folder, "Makefile.in")
replace_in_file(self, makefile_in,
"DSO_LDFLAGS = @DSO_LDFLAGS@",
"DSO_LDFLAGS = @DSO_LDFLAGS@ -Wl,--out-implib,lib/libjemalloc.a", strict=False)
replace_in_file(self, makefile_in,
"\t$(INSTALL) -d $(LIBDIR)\n"
"\t$(INSTALL) -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(LIBDIR)",
"\t$(INSTALL) -d $(BINDIR)\n"
"\t$(INSTALL) -d $(LIBDIR)\n"
"\t$(INSTALL) -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(BINDIR)\n"
"\t$(INSTALL) -m 644 $(objroot)lib/libjemalloc.a $(LIBDIR)", strict=False)

apply_conandata_patches(self)

tc.configure_args.append("--enable-prof")
env = tc.environment()
if is_msvc(self):
# Do not check whether the math library exists when compiled by MSVC
# because MSVC treats the function `char log()` as a intrinsic function
# and therefore complains about insufficient arguments passed to the function
tc.configure_args.append("ac_cv_search_log=none required")
env.define("CC", "cl")
env.define("CXX", "cl")
tc.generate(env)

def build(self):
self._patch_sources()
if self.settings.compiler == "Visual Studio":
with tools_legacy.vcvars(self.settings) if self.settings.compiler == "Visual Studio" else tools_legacy.no_op():
with tools_legacy.environment_append({"CC": "cl", "CXX": "cl"}) if self.settings.compiler == "Visual Studio" else tools_legacy.no_op():
with tools_legacy.chdir(self.source_folder):
# Do not use AutoToolsBuildEnvironment because we want to run configure as ./configure
self.run("./configure {}".format(" ".join(self._autotools_args)), win_bash=tools_legacy.os_info.is_windows)
msbuild = MSBuild(self)
# Do not use the 2015 solution: unresolved external symbols: test_hooks_libc_hook and test_hooks_arena_new_hook
sln_file = os.path.join(self.source_folder, "msvc", "jemalloc_vc2017.sln")
msbuild.build(sln_file, targets=["jemalloc"], build_type=self._msvc_build_type)
else:
autotools = self._configure_autotools()
autotools.make()

@property
def _library_name(self):
libname = "jemalloc"
if self.settings.compiler == "Visual Studio":
if self.options.shared:
if self.settings.build_type == "Debug":
libname += "d"
else:
toolset = tools_legacy.msvs_toolset(self.settings)
toolset_number = "".join(c for c in toolset if c in string.digits)
libname += "-vc{}-{}".format(toolset_number, self._msvc_build_type)
else:
if self.settings.os == "Windows":
if not self.options.shared:
libname += "_s"
else:
if not self.options.shared and self.options.fPIC:
libname += "_pic"
return libname
apply_conandata_patches(self)
autotools = Autotools(self)
autotools.configure()
autotools.make()

def package(self):
self.copy(pattern="COPYING", src=self.source_folder, dst="licenses")
if self.settings.compiler == "Visual Studio":
arch_subdir = {
"x86_64": "x64",
"x86": "x86",
}[str(self.settings.arch)]
self.copy("*.lib", src=os.path.join(self.source_folder, "msvc", arch_subdir, self._msvc_build_type), dst=os.path.join(self.package_folder, "lib"))
self.copy("*.dll", src=os.path.join(self.source_folder, "msvc", arch_subdir, self._msvc_build_type), dst=os.path.join(self.package_folder, "bin"))
self.copy("jemalloc.h", src=os.path.join(self.source_folder, "include", "jemalloc"), dst=os.path.join(self.package_folder, "include", "jemalloc"), keep_path=True)
copy(self, pattern="COPYING*", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
autotools = Autotools(self)
autotools.install(target="install_lib_shared" if self.options.shared else "install_lib_static")
autotools.install(target="install_include")
if self.settings.os == "Windows" and self.settings.compiler == "gcc":
rename(self, os.path.join(self.package_folder, "lib", f"{self._library_name}.lib"),
os.path.join(self.package_folder, "lib", f"lib{self._library_name}.a"))
if not self.options.shared:
os.unlink(os.path.join(self.package_folder, "lib", "jemalloc.lib"))
if is_msvc(self):
shutil.copytree(os.path.join(self.source_folder, "include", "msvc_compat"),
os.path.join(self.package_folder, "include", "msvc_compat"))
else:
autotools = self._configure_autotools()
# Use install_lib_XXX and install_include to avoid mixing binaries and dll's
autotools.make(target="install_lib_shared" if self.options.shared else "install_lib_static")
autotools.make(target="install_include")
if self.settings.os == "Windows" and self.settings.compiler == "gcc":
rename(self, os.path.join(self.package_folder, "lib", "{}.lib".format(self._library_name)),
os.path.join(self.package_folder, "lib", "lib{}.a".format(self._library_name)))
if not self.options.shared:
os.unlink(os.path.join(self.package_folder, "lib", "jemalloc.lib"))

def package_info(self):
self.cpp_info.names["pkg_config"] = "jemalloc"
self.cpp_info.set_property("pkg_config_name", "jemalloc")
self.cpp_info.libs = [self._library_name]
self.cpp_info.includedirs = [os.path.join(self.package_folder, "include"),
os.path.join(self.package_folder, "include", "jemalloc")]
if self.settings.compiler == "Visual Studio":
if is_msvc(self):
self.cpp_info.includedirs.append(os.path.join(self.package_folder, "include", "msvc_compat"))
if not self.options.shared:
self.cpp_info.defines = ["JEMALLOC_EXPORT="]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/configure.ac b/configure.ac
index f6d25f334..3115504e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1592,7 +1592,7 @@ fi
[enable_uaf_detection="0"]
)
if test "x$enable_uaf_detection" = "x1" ; then
- AC_DEFINE([JEMALLOC_UAF_DETECTION], [ ])
+ AC_DEFINE([JEMALLOC_UAF_DETECTION], [ ], ["enable UAF"])
fi
AC_SUBST([enable_uaf_detection])

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/configure.ac b/configure.ac
index 3115504e2..ffb504b08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -749,6 +749,7 @@ case "${host}" in
so="dll"
if test "x$je_cv_msvc" = "xyes" ; then
importlib="lib"
+ JE_APPEND_VS(CPPFLAGS, -DJEMALLOC_NO_PRIVATE_NAMESPACE)
DSO_LDFLAGS="-LD"
EXTRA_LDFLAGS="-link -DEBUG"
CTARGET='-Fo$@'
9 changes: 4 additions & 5 deletions recipes/jemalloc/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(test_package LANGUAGES CXX)
project(test_package)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
find_package(jemalloc REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
set_property(TARGET ${CMAKE_PROJECT_NAME} PROPERTY CXX_STANDARD 11)
target_link_libraries(${PROJECT_NAME} PRIVATE jemalloc::jemalloc)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
21 changes: 15 additions & 6 deletions recipes/jemalloc/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
from conans import ConanFile, CMake, tools
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import CMake, cmake_layout
import os


class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)

def layout(self):
cmake_layout(self)

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

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
8 changes: 8 additions & 0 deletions recipes/jemalloc/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(test_package)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package
${CMAKE_CURRENT_BINARY_DIR}/test_package)
Loading