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

New modernized recipes for zlib and bzip2 #6474

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions recipes/bzip2/all/CMakeLists.txt
Expand Up @@ -3,15 +3,12 @@ project(bzip2 C)

include(GNUInstallDirs)

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

if(MSVC OR MSVC90 OR MSVC10)
set(MSVC ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

set(SOURCE_SUBFOLDER ${CMAKE_CURRENT_SOURCE_DIR}/source_subfolder)
set(SOURCE_SUBFOLDER ${CMAKE_CURRENT_SOURCE_DIR})
set(BZ2_LIBRARY bz2)

option(BZ2_BUILD_EXE ON)
Expand Down
60 changes: 28 additions & 32 deletions recipes/bzip2/all/conanfile.py
@@ -1,8 +1,10 @@
import os
import textwrap
from conans import ConanFile, CMake, tools
from conans import ConanFile, tools
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we start to try to replace all the tools.xxx also? (in general all the conans imports)

from conan.tools.cmake import CMake, CMakeToolchain
from conan.tools.layout import cmake_layout

required_conan_version = ">=1.33.0"
required_conan_version = ">=1.38.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, we need to update the CI. I think we are running 1.37.2



class Bzip2Conan(ConanFile):
Expand All @@ -11,7 +13,7 @@ class Bzip2Conan(ConanFile):
homepage = "http://www.bzip.org"
license = "bzip2-1.0.8"
description = "bzip2 is a free and open-source file compression program that uses the Burrows Wheeler algorithm."
topics = ("conan", "bzip2", "data-compressor", "file-compression")
topics = ("bzip2", "data-compressor", "file-compression")

settings = "os", "compiler", "arch", "build_type"
options = {
Expand All @@ -26,12 +28,6 @@ class Bzip2Conan(ConanFile):
}

exports_sources = ["CMakeLists.txt", "patches/**"]
generators = "cmake"
_cmake = None

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

def config_options(self):
if self.settings.os == "Windows":
Expand All @@ -45,27 +41,32 @@ def configure(self):
del self.settings.compiler.cppstd

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

def _configure_cmake(self):
if self._cmake:
return self._cmake
self._cmake = CMake(self)
self._cmake.definitions["BZ2_VERSION_STRING"] = self.version
self._cmake.definitions["BZ2_VERSION_MAJOR"] = tools.Version(self.version).major
self._cmake.definitions["BZ2_BUILD_EXE"] = self.options.build_executable
self._cmake.configure()
return self._cmake
tools.get(**self.conan_data["sources"][self.version], destination=self.source_folder, strip_root=True)
# FIXME: this is failing after the export export to "src" in local folder
try:
os.rename("CMakeLists.txt", "src/CMakeLists.txt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
os.rename("CMakeLists.txt", "src/CMakeLists.txt")
tools.rename("CMakeLists.txt", "src/CMakeLists.txt")

Is it capable of moving files ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but only when the target directory is already created.

except:
pass

def layout(self):
cmake_layout(self)

def generate(self):
cmake_toolchain = CMakeToolchain(self)
cmake_toolchain.variables["BZ2_VERSION_STRING"] = self.version
cmake_toolchain.variables["BZ2_VERSION_MAJOR"] = tools.Version(self.version).major
cmake_toolchain.variables["BZ2_BUILD_EXE"] = self.options.build_executable
cmake_toolchain.generate()

def build(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
cmake = self._configure_cmake()
tools.files.apply_conandata_patches(self)
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
self.copy("LICENSE", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
self.copy("LICENSE", dst="licenses")
cmake = CMake(self)
cmake.install()
self._create_cmake_module_variables(
os.path.join(self.package_folder, self._module_subfolder, self._module_file)
Expand Down Expand Up @@ -100,13 +101,8 @@ def _module_file(self):
return "conan-official-{}-variables.cmake".format(self.name)

def package_info(self):
self.cpp_info.names["cmake_find_package"] = "BZip2"
self.cpp_info.names["cmake_find_package_multi"] = "BZip2"
self.cpp_info.builddirs.append(self._module_subfolder)
self.cpp_info.build_modules["cmake_find_package"] = [os.path.join(self._module_subfolder, self._module_file)]
self.cpp_info.libs = ["bz2"]

if self.options.build_executable:
bin_path = os.path.join(self.package_folder, "bin")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got appending the path implicit somehow? If yes, through what?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We expect the consumers to use the VirtualRunEnv when need it instead of filling the PATH by default with stuff with might never need.

self.output.info("Appending PATH environment variable: {}".format(bin_path))
self.env_info.PATH.append(bin_path)
self.cpp_info.set_property("cmake_file_name", "BZip2")
self.cpp_info.set_property("cmake_target_name", "BZip2")
16 changes: 12 additions & 4 deletions recipes/bzip2/all/test_package/conanfile.py
@@ -1,17 +1,25 @@
import os
from conans import ConanFile, CMake, tools
from conans import ConanFile, tools
from conan.tools.cmake import CMake
from conan.tools.layout import cmake_layout


class TestPackageConan(ConanFile):
settings = "os", "compiler", "arch", "build_type"
generators = "cmake", "cmake_find_package"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This VirtualRunEnv, we could discuss if we want it explicit or implicit.
Its goal is to be able to run with shared libraries, the conan create . -o lib:shared=True works with this.
There is [conf] to automatically use it without explicit instantiation, but the invocation self.run("%s --help" % cmd, env=["conanrunenv"]) still needs to specify conanrunenv, and this is not injected by default.


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

def configure(self):
del self.settings.compiler.libcxx

def layout(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to be unused (e.g. never called), it is needed? if so, why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the new layout() built-in Conan method to define the package layout, it is called internally by Conan, like other methods: https://docs.conan.io/en/latest/reference/conanfile/methods.html#layout

Copy link
Contributor

@SSE4 SSE4 Jul 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reading about feature, I don't get why is it needed for test package?

You can declare a layout() method in the recipe to describe the package contents, not only the final package in the 
cache but also the package while developing. As the package will have the same structure in the cache and in our 
local directory, the recipe development becomes easier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not "needed" but nice to use always the same layout, more clear, and easy to explore the build files in case you need.

cmake_layout(self)

def test(self):
if not tools.cross_building(self.settings):
bin_path = os.path.join("bin", "test_package")
self.run("%s --help" % bin_path, run_environment=True)
cmd = os.path.join(self.cpp.build.bindirs[0], "test_package")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if it's safe, e.g. if bindirs is an empty

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bindir of the current package. As you are declaring the layout(), you know there is always a bindir. Actually were always a bindir unless you remove it from the cppinfo.

self.run("%s --help" % cmd, env=["conanrunenv"])
@@ -1,9 +1,6 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

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

find_package(BZip2 REQUIRED)
message("BZIP2_FOUND: ${BZIP2_FOUND}")
message("BZIP2_NEED_PREFIX: ${BZIP2_NEED_PREFIX}")
Expand Down
9 changes: 0 additions & 9 deletions recipes/zlib/1.2.11/CMakeLists.txt

This file was deleted.

2 changes: 0 additions & 2 deletions recipes/zlib/1.2.11/conandata.yml
Expand Up @@ -8,6 +8,4 @@ sources:
patches:
"1.2.11":
- patch_file: "patches/0002-gzguts-xcode12-compile-fix.patch"
base_path: "source_subfolder"
- patch_file: "patches/0003-cmake-fix-msys2-subsystem.patch"
base_path: "source_subfolder"
68 changes: 33 additions & 35 deletions recipes/zlib/1.2.11/conanfile.py
@@ -1,5 +1,7 @@
import os
from conans import ConanFile, tools, CMake
from conans import ConanFile, tools
from conan.tools.cmake import CMake
from conan.tools.layout import cmake_layout
from conans.errors import ConanException


Expand All @@ -14,17 +16,9 @@ class ZlibConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
options = {"shared": [True, False], "fPIC": [True, False], "minizip": [True, False, "deprecated"]}
default_options = {"shared": False, "fPIC": True, "minizip": "deprecated"}
exports_sources = ["CMakeLists.txt", "CMakeLists_minizip.txt", "patches/**"]
generators = "cmake"
topics = ("conan", "zlib", "compression")

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

@property
def _build_subfolder(self):
return "build_subfolder"
exports_sources = ["patches/**"]
generators = "CMakeToolchain", "CMakeDeps"
topics = ("zlib", "compression")

def config_options(self):
if self.settings.os == "Windows":
Expand All @@ -44,13 +38,14 @@ def package_id(self):
del self.info.options.minizip

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

def _patch_sources(self):
for patch in self.conan_data["patches"][self.version]:
tools.patch(**patch)
with tools.chdir(".."): # FIXME: This need to go to parent folder is not very nice.
for patch in self.conan_data["patches"][self.version]:
tools.patch(**patch, base_path=self.source_folder)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See conan-io/conan#9361
apply_conandata_patches can be used to follow the layout automatically.


with tools.chdir(self._source_subfolder):
with tools.chdir(self.source_folder):
# https://github.com/madler/zlib/issues/268
tools.replace_in_file('gzguts.h',
'#if defined(_WIN32) || defined(__CYGWIN__)',
Expand All @@ -60,19 +55,22 @@ def _patch_sources(self):
if not is_apple_clang12:
for filename in ['zconf.h', 'zconf.h.cmakein', 'zconf.h.in']:
tools.replace_in_file(filename,
'#ifdef HAVE_UNISTD_H '
'/* may be set to #if 1 by ./configure */',
'#if defined(HAVE_UNISTD_H) && (1-HAVE_UNISTD_H-1 != 0)')
'#ifdef HAVE_UNISTD_H '
'/* may be set to #if 1 by ./configure */',
'#if defined(HAVE_UNISTD_H) && (1-HAVE_UNISTD_H-1 != 0)')
tools.replace_in_file(filename,
'#ifdef HAVE_STDARG_H '
'/* may be set to #if 1 by ./configure */',
'#if defined(HAVE_STDARG_H) && (1-HAVE_STDARG_H-1 != 0)')
'#ifdef HAVE_STDARG_H '
'/* may be set to #if 1 by ./configure */',
'#if defined(HAVE_STDARG_H) && (1-HAVE_STDARG_H-1 != 0)')

def layout(self):
cmake_layout(self)

def build(self):
self._patch_sources()
make_target = "zlib" if self.options.shared else "zlibstatic"
cmake = CMake(self)
cmake.configure(build_folder=self._build_subfolder)
cmake.configure()
cmake.build(target=make_target)

def _rename_libraries(self):
Expand All @@ -97,33 +95,33 @@ def _rename_libraries(self):
tools.rename(current_lib, os.path.join(lib_path, "zlib.lib"))

def _extract_license(self):
with tools.chdir(os.path.join(self.source_folder, self._source_subfolder)):
with tools.chdir(self.source_folder):
tmp = tools.load("zlib.h")
license_contents = tmp[2:tmp.find("*/", 1)]
tools.save("LICENSE", license_contents)

def package(self):
self._extract_license()
self.copy("LICENSE", src=self._source_subfolder, dst="licenses")
self.copy("LICENSE", dst="licenses")

# Copy headers
for header in ["*zlib.h", "*zconf.h"]:
self.copy(pattern=header, dst="include", src=self._source_subfolder, keep_path=False)
self.copy(pattern=header, dst="include", src=self._build_subfolder, keep_path=False)
self.copy(pattern=header, dst="include", keep_path=False)
self.copy(pattern=header, dst="include", keep_path=False)

# Copying static and dynamic libs
if self.options.shared:
self.copy(pattern="*.dylib*", dst="lib", src=self._build_subfolder, keep_path=False, symlinks=True)
self.copy(pattern="*.so*", dst="lib", src=self._build_subfolder, keep_path=False, symlinks=True)
self.copy(pattern="*.dll", dst="bin", src=self._build_subfolder, keep_path=False)
self.copy(pattern="*.dll.a", dst="lib", src=self._build_subfolder, keep_path=False)
self.copy(pattern="*.dylib*", dst="lib", keep_path=False, symlinks=True)
self.copy(pattern="*.so*", dst="lib", keep_path=False, symlinks=True)
self.copy(pattern="*.dll", dst="bin", keep_path=False)
self.copy(pattern="*.dll.a", dst="lib", keep_path=False)
else:
self.copy(pattern="*.a", dst="lib", src=self._build_subfolder, keep_path=False)
self.copy(pattern="*.lib", dst="lib", src=self._build_subfolder, keep_path=False)
self.copy(pattern="*.a", dst="lib", keep_path=False)
self.copy(pattern="*.lib", dst="lib", keep_path=False)

self._rename_libraries()

def package_info(self):
self.cpp_info.libs.append("zlib" if self.settings.os == "Windows" and not self.settings.os.subsystem else "z")
self.cpp_info.names["cmake_find_package"] = "ZLIB"
self.cpp_info.names["cmake_find_package_multi"] = "ZLIB"
self.cpp_info.set_property("cmake_file_name", "ZLIB")
self.cpp_info.set_property("cmake_target_name", "ZLIB")
19 changes: 14 additions & 5 deletions recipes/zlib/1.2.11/test_package/conanfile.py
@@ -1,9 +1,11 @@
import os
from conans import ConanFile, CMake, tools
from conans import ConanFile, tools
from conan.tools.cmake import CMake
from conan.tools.layout import cmake_layout

class TestZlibConan(ConanFile):
settings = "os", "compiler", "arch", "build_type"
generators = "cmake", "pkg_config"
generators = "CMakeDeps", "CMakeToolchain", "PkgConfigDeps", "VirtualRunEnv"

def configure(self):
del self.settings.compiler.libcxx
Expand All @@ -13,8 +15,15 @@ def build(self):
cmake.configure()
cmake.build()

def layout(self):
cmake_layout(self)

def generate(self):
# Necessary modernization, as test() doesn't have self.dependencies yet.
assert os.path.exists(os.path.join(self.dependencies["zlib"].package_folder, "licenses", "LICENSE"))

def test(self):
assert os.path.exists(os.path.join(self.deps_cpp_info["zlib"].rootpath, "licenses", "LICENSE"))
assert os.path.exists(os.path.join(self.build_folder, "zlib.pc"))
assert os.path.exists(os.path.join(self.generators_folder, "zlib.pc"))
if "x86" in self.settings.arch and not tools.cross_building(self.settings):
self.run(os.path.join("bin", "test"), run_environment=True)
cmd = os.path.join(self.cpp.build.bindirs[0], "test")
self.run(cmd, env="conanrunenv")
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.0)
project(test_package C)

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

add_executable(test_zlib test.c)
target_link_libraries(test_zlib CONAN_PKG::zlib)
target_link_libraries(test_zlib ZLIB::ZLIB)
set_target_properties(test_zlib PROPERTIES OUTPUT_NAME "test")