diff --git a/recipes/nspr/all/conanfile.py b/recipes/nspr/all/conanfile.py index b0ce8c9099e1bb..e3798c3dcce58e 100644 --- a/recipes/nspr/all/conanfile.py +++ b/recipes/nspr/all/conanfile.py @@ -1,24 +1,29 @@ -from conan.tools.microsoft import msvc_runtime_flag -from conan.tools.files import rename, get, rmdir, chdir, replace_in_file -from conan.tools.scm import Version +import os +import shutil + from conan import ConanFile from conan.errors import ConanInvalidConfiguration -from conans import tools, AutoToolsBuildEnvironment -import contextlib -import functools -import os +from conan.tools.apple import is_apple_os +from conan.tools.env import Environment +from conan.tools.files import chdir, copy, get, rename, replace_in_file, rmdir, mkdir +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 -required_conan_version = ">=1.47.0" +required_conan_version = ">=1.53.0" class NsprConan(ConanFile): name = "nspr" - homepage = "https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR" - description = "Netscape Portable Runtime (NSPR) provides a platform-neutral API for system level and libc-like functions." - topics = ("nspr", "libc") - url = "https://github.com/conan-io/conan-center-index" + description = ("Netscape Portable Runtime (NSPR) provides a platform-neutral API" + " for system level and libc-like functions.") license = "MPL-2.0" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR" + topics = ("libc",) + package_type = "library" settings = "os", "arch", "compiler", "build_type" options = { "shared": [True, False], @@ -33,14 +38,6 @@ class NsprConan(ConanFile): "win32_target": "winnt", } - @property - def _is_msvc(self): - return str(self.settings.compiler) in ["Visual Studio", "msvc"] - - @property - def _source_subfolder(self): - return "source_subfolder" - @property def _settings_build(self): return getattr(self, "settings_build", self.settings) @@ -49,128 +46,127 @@ def config_options(self): if self.settings.os == "Windows": del self.options.fPIC else: - del self.options.win32_target + self.options.rm_safe("win32_target") def configure(self): if self.options.shared: - del self.options.fPIC - del self.settings.compiler.cppstd - del self.settings.compiler.libcxx + self.options.rm_safe("fPIC") + self.settings.rm_safe("compiler.cppstd") + self.settings.rm_safe("compiler.libcxx") + + def layout(self): + basic_layout(self, src_folder="src") def validate(self): # https://bugzilla.mozilla.org/show_bug.cgi?id=1658671 if Version(self.version) < "4.29": - if self.settings.os == "Macos" and self.settings.arch == "armv8": + if is_apple_os(self) and self.settings.arch == "armv8": raise ConanInvalidConfiguration("NSPR does not support mac M1 before 4.29") def build_requirements(self): if self._settings_build.os == "Windows": - self.build_requires("mozilla-build/3.3") - if not tools.get_env("CONAN_BASH_PATH"): - self.build_requires("msys2/cci.latest") + self.tool_requires("mozilla-build/3.3") + 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="tmp", strip_root=True) - rename(self, os.path.join("tmp", "nspr"), self._source_subfolder) - rmdir(self, "tmp") - - @contextlib.contextmanager - def _build_context(self): - if self._is_msvc: - with tools.vcvars(self): - with tools.environment_append({"CC": "cl", "CXX": "cl", "LD": "link"}): - yield - else: - yield + with chdir(self, self.export_sources_folder): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + rmdir(self, self.source_folder) + rename(self, "nspr", self.source_folder) - @functools.lru_cache(1) - def _configure_autotools(self): - autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows) + def generate(self): + tc = AutotoolsToolchain(self) yes_no = lambda v: "yes" if v else "no" - conf_args = [ + tc.configure_args += [ "--with-mozilla={}".format(yes_no(self.options.with_mozilla)), "--enable-64bit={}".format(yes_no(self.settings.arch in ("armv8", "x86_64", "mips64", "ppc64", "ppc64le"))), "--enable-strip={}".format(yes_no(self.settings.build_type not in ("Debug", "RelWithDebInfo"))), "--enable-debug={}".format(yes_no(self.settings.build_type == "Debug")), - "--datarootdir={}".format(tools.unix_path(os.path.join(self.package_folder, "res"))), + "--datarootdir=${prefix}/res", "--disable-cplus", ] - if self._is_msvc: - conf_args.extend([ + if is_msvc(self): + tc.configure_args += [ "{}-pc-mingw32".format("x86_64" if self.settings.arch == "x86_64" else "x86"), - "--enable-static-rtl={}".format(yes_no("MT" in msvc_runtime_flag(self))), + "--enable-static-rtl={}".format(yes_no(is_msvc_static_runtime(self))), "--enable-debug-rtl={}".format(yes_no("d" in msvc_runtime_flag(self))), - ]) + ] elif self.settings.os == "Android": - conf_args.extend([ - "--with-android-ndk={}".format(tools.get_env(["NDK_ROOT"])), + tc.configure_args += [ + "--with-android-ndk={}".format(os.environ.get("NDK_ROOT", "")), "--with-android-version={}".format(self.settings.os.api_level), - "--with-android-platform={}".format(tools.get_env("ANDROID_PLATFORM")), - "--with-android-toolchain={}".format(tools.get_env("ANDROID_TOOLCHAIN")), - ]) + "--with-android-platform={}".format(os.environ.get("ANDROID_PLATFORM")), + "--with-android-toolchain={}".format(os.environ.get("ANDROID_TOOLCHAIN")), + ] elif self.settings.os == "Windows": - conf_args.append("--enable-win32-target={}".format(self.options.win32_target)) - env = autotools.vars - if self.settings.os == "Macos": - if self.settings.arch == "armv8": - # conan adds `-arch`, which conflicts with nspr's apple silicon support - env["CFLAGS"] = env["CFLAGS"].replace("-arch arm64", "") - env["CXXFLAGS"] = env["CXXFLAGS"].replace("-arch arm64", "") - - autotools.configure(args=conf_args, vars=env) - return autotools + tc.configure_args.append("--enable-win32-target={}".format(self.options.win32_target)) + if is_apple_os(self) and self.settings.arch == "armv8": + # conan adds `-arch`, which conflicts with nspr's apple silicon support + tc.cflags.remove("-arch arm64") + tc.cxxflags.remove("-arch arm64") + tc.generate() + + if is_msvc(self): + env = Environment() + env.define("CC", "cl") + env.define("CXX", "cl") + env.define("LD", "link") + env.vars(self).save_script("conanbuild_msvc") def build(self): - with chdir(self, self._source_subfolder): + with chdir(self, self.source_folder): # relocatable shared libs on macOS - replace_in_file(self, - "configure", - "-install_name @executable_path/", - "-install_name @rpath/" - ) - with self._build_context(): - autotools = self._configure_autotools() - autotools.make() + replace_in_file(self, "configure", "-install_name @executable_path/", "-install_name @rpath/") + autotools = Autotools(self) + autotools.configure() + autotools.make() def package(self): - self.copy(pattern="LICENSE", dst="licenses", src=self._source_subfolder) - with chdir(self, self._source_subfolder): - with self._build_context(): - autotools = self._configure_autotools() - autotools.install() + copy(self, "LICENSE", + dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder) + with chdir(self, self.source_folder): + autotools = Autotools(self) + autotools.install() rmdir(self, os.path.join(self.package_folder, "bin")) rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) rmdir(self, os.path.join(self.package_folder, "share")) + if os.path.exists(os.path.join(self.package_folder, "include", "nspr.h")): + with chdir(self, self.package_folder): + rename(self, "include", "nspr") + mkdir(self, "include") + shutil.move("nspr", "include") if self.settings.os == "Windows": if self.options.shared: os.mkdir(os.path.join(self.package_folder, "bin")) for lib in self._library_names: - libsuffix = "lib" if self._is_msvc else "a" - libprefix = "" if self._is_msvc else "lib" + libsuffix = "lib" if is_msvc(self) else "a" + libprefix = "" if is_msvc(self) else "lib" if self.options.shared: os.unlink(os.path.join(self.package_folder, "lib", f"{libprefix}{lib}_s.{libsuffix}")) - rename(self, os.path.join(self.package_folder, "lib", f"{lib}.dll"), - os.path.join(self.package_folder, "bin", f"{lib}.dll")) + rename(self, + os.path.join(self.package_folder, "lib", f"{lib}.dll"), + os.path.join(self.package_folder, "bin", f"{lib}.dll")) else: os.unlink(os.path.join(self.package_folder, "lib", f"{libprefix}{lib}.{libsuffix}")) os.unlink(os.path.join(self.package_folder, "lib", f"{lib}.dll")) if not self.options.shared: replace_in_file(self, os.path.join(self.package_folder, "include", "nspr", "prtypes.h"), - "#define NSPR_API(__type) PR_IMPORT(__type)", - "#define NSPR_API(__type) extern __type") + "#define NSPR_API(__type) PR_IMPORT(__type)", + "#define NSPR_API(__type) extern __type") replace_in_file(self, os.path.join(self.package_folder, "include", "nspr", "prtypes.h"), - "#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)", - "#define NSPR_DATA_API(__type) extern __type") + "#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)", + "#define NSPR_DATA_API(__type) extern __type") else: - shared_ext = "dylib" if self.settings.os == "Macos" else "so" + shared_ext = "dylib" if is_apple_os(self) else "so" for lib in self._library_names: if self.options.shared: os.unlink(os.path.join(self.package_folder, "lib", f"lib{lib}.a")) else: os.unlink(os.path.join(self.package_folder, "lib", f"lib{lib}.{shared_ext}")) - if self._is_msvc: + if is_msvc(self): if self.settings.build_type == "Debug": for lib in self._library_names: os.unlink(os.path.join(self.package_folder, "lib", f"{lib}.pdb")) @@ -200,8 +196,8 @@ def package_info(self): elif self.settings.os == "Windows": self.cpp_info.system_libs.extend(["winmm", "ws2_32"]) - aclocal = tools.unix_path(os.path.join(self.package_folder, "res", "aclocal")) + self.cpp_info.resdirs = ["res"] + + aclocal = unix_path(self, os.path.join(self.package_folder, "res", "aclocal")) self.output.info(f"Appending AUTOMAKE_CONAN_INCLUDES environment variable: {aclocal}") self.env_info.AUTOMAKE_CONAN_INCLUDES.append(aclocal) - - self.cpp_info.resdirs = ["res"] diff --git a/recipes/nspr/all/test_package/CMakeLists.txt b/recipes/nspr/all/test_package/CMakeLists.txt index e8bb34d55a6376..898448a11de583 100644 --- a/recipes/nspr/all/test_package/CMakeLists.txt +++ b/recipes/nspr/all/test_package/CMakeLists.txt @@ -1,9 +1,6 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.15) project(test_package C) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGETS) - find_package(nspr REQUIRED CONFIG) add_executable(${PROJECT_NAME} test_package.c) diff --git a/recipes/nspr/all/test_package/conanfile.py b/recipes/nspr/all/test_package/conanfile.py index ab912e4e61df1a..d6a48b7c16ccf6 100644 --- a/recipes/nspr/all/test_package/conanfile.py +++ b/recipes/nspr/all/test_package/conanfile.py @@ -1,19 +1,29 @@ -from conans import ConanFile, CMake, tools +from conan import ConanFile +from conan.tools.apple import is_apple_os +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake import os class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package_multi" + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) def build_requirements(self): - if self.settings.os == "Macos" and self.settings.arch == "armv8": + if is_apple_os(self) and self.settings.arch == "armv8": # Workaround for CMake bug with error message: # Attempting to use @rpath without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being # set. This could be because you are using a Mac OS X version less than 10.5 # or because CMake's platform configuration is corrupt. # FIXME: Remove once CMake on macOS/M1 CI runners is upgraded. - self.build_requires("cmake/3.22.0") + self.tool_requires("cmake/3.22.0") + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) @@ -21,6 +31,6 @@ def build(self): cmake.build() def test(self): - if not tools.cross_building(self): - bin_path = os.path.join("bin", "test_package") - self.run(bin_path, run_environment=True) + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/nspr/all/test_v1_package/CMakeLists.txt b/recipes/nspr/all/test_v1_package/CMakeLists.txt new file mode 100644 index 00000000000000..91630d79f4abb3 --- /dev/null +++ b/recipes/nspr/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/ + ${CMAKE_CURRENT_BINARY_DIR}/test_package/) diff --git a/recipes/nspr/all/test_v1_package/conanfile.py b/recipes/nspr/all/test_v1_package/conanfile.py new file mode 100644 index 00000000000000..9f6cd40d88fedb --- /dev/null +++ b/recipes/nspr/all/test_v1_package/conanfile.py @@ -0,0 +1,27 @@ +from conan.tools.apple import is_apple_os +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake", "cmake_find_package_multi" + + def build_requirements(self): + if is_apple_os(self) and self.settings.arch == "armv8": + # Workaround for CMake bug with error message: + # Attempting to use @rpath without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being + # set. This could be because you are using a Mac OS X version less than 10.5 + # or because CMake's platform configuration is corrupt. + # FIXME: Remove once CMake on macOS/M1 CI runners is upgraded. + self.build_requires("cmake/3.22.0") + + 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)