Skip to content

Commit

Permalink
Merge branch 'conan-io:master' into CURA-8831_autoconf
Browse files Browse the repository at this point in the history
  • Loading branch information
jellespijker authored Sep 10, 2022
2 parents 36827a6 + 1b6b496 commit 29fe03c
Show file tree
Hide file tree
Showing 305 changed files with 5,924 additions and 2,277 deletions.
3 changes: 3 additions & 0 deletions .c3i/authorized_users.yml
Original file line number Diff line number Diff line change
Expand Up @@ -928,3 +928,6 @@ authorized_users:
- "BjoernAtBosch"
- "dubvulture"
- "ZbigniewRA"
- "JorgenPo"
- "AlexRamallo"
- "kissandras"
11 changes: 11 additions & 0 deletions docs/faqs.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ No. Some projects provide more than a simple library, but also applications. For
When a non standard open-source license is used, we have decided to use `LicenseRef-` as a prefix, followed by the name of the file which contains a custom license.
See [the reviewing guidlines](reviewing.md#license-attribute) for more details.

## How do I flag a problem to a recipe consumer?

Regardless of why, if the recipe detects a problem where binaries might not be generated correctly, an exception must be raised. This to prevent the publishing
incorrect packages which do not work as intented. Use `ConanInvalidConfiguration` which is specially support in ConanCenter.

```py
raise ConanInvalidConfiguration(f"The project {self.ref} requires liba.enable_feature=True.")
```

You should not be using the `self.output.warn` and it is not enough to alter consumers or stop the build service.

## Why is a `build.check_min_cppstd` call not enough?

Very often C++ projects require a minimum standard version, such as 14 or 17, in order to compile. Conan offers tools which enable checking the relevant setting is enabled and above this support for a certain version is present. Otherwise, it uses the compiler's default.
Expand Down
File renamed without changes.
132 changes: 132 additions & 0 deletions docs/package_templates/autotools_package/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.env import VirtualBuildEnv
from conan.tools.build import check_min_cppstd
from conan.tools.files import copy, get, rm, rmdir, apply_conandata_patches
from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps, PkgConfigDeps
from conan.tools.layout import basic_layout
import os


required_conan_version = ">=1.51.3"


class PackageConan(ConanFile):
name = "package"
description = "short description"
license = "" # Use short name only, conform to SPDX License List: https://spdx.org/licenses/
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/project/package"
topics = ("topic1", "topic2", "topic3") # no "conan" and project name in topics
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_foobar": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"with_foobar": True,
}

# no exports_sources attribute, but export_sources(self) method instead
# this allows finer grain exportation of patches per version
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:
try:
del self.options.fPIC # once removed by config_options, need try..except for a second del
except Exception:
pass
try:
del self.settings.compiler.libcxx # for plain C projects only
except Exception:
pass
try:
del self.settings.compiler.cppstd # for plain C projects only
except Exception:
pass

def layout(self):
basic_layout(self, src_folder="src") # src_folder must use the same source folder name the project

def requirements(self):
self.requires("dependency/0.8.1") # prefer self.requires method instead of requires attribute
if self.options.with_foobar:
self.requires("foobar/0.1.0")

def validate(self):
# validate the minimum cpp standard supported. Only for C++ projects
if self.info.settings.compiler.cppstd:
check_min_cppstd(self, 11)
if self.info.settings.os not in ["Linux", "FreeBSD", "MacOS"]:
raise ConanInvalidConfiguration(f"{self.ref} is not supported on {self.info.settings.os}.")

# if another tool than the compiler or autotools is required to build the project (pkgconf, bison, flex etc)
def build_requirements(self):
self.tool_requires("libtool/x.y.z")
self.tool_requires("pkgconf/x.y.z")

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

def generate(self):
# autotools usually uses 'yes' and 'no' to enable/disable options
yes_no = lambda v: "yes" if v else "no"
# --fpic is automatically managed when 'fPIC'option is declared
# --enable/disable-shared is automatically managed when 'shared' option is declared
tc = AutotoolsToolchain(self)
tc.configure_args.append("--with-foobar=%s" % yes_no(self.options.with_foobar))
tc.configure_args.append("--enable-tools=no")
tc.configure_args.append("--enable-manpages=no")
tc.generate()
# generate dependencies for pkg-config
tc = PkgConfigDeps(self)
tc.generate()
# generate dependencies for autotools
tc = AutotoolsDeps(self)
tc.generate()
# inject tools_require env vars in build context
ms = VirtualBuildEnv(self)
ms.generate(scope="build")

def build(self):
# apply patches listed in conandata.yml
apply_conandata_patches(self)
autotools = Autotools(self)
# run autoreconf to generate configure file
autotools.autoreconf()
# ./configure + toolchain file
autotools.configure()
autotools.make()

def package(self):
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
autotools = Autotools(self)
autotools.install()

# some files extensions and folders are not allowed. Please, read the FAQs to get informed.
rm(self, "*.la", os.path.join(self.package_folder, "lib"))
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 = ["package_lib"]

# if package provides a pkgconfig file (package.pc, usually installed in <prefix>/lib/pkgconfig/)
self.cpp_info.set_property("pkg_config_name", "package")

# If they are needed on Linux, m, pthread and dl are usually needed on FreeBSD too
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.system_libs.append("m")
self.cpp_info.system_libs.append("pthread")
self.cpp_info.system_libs.append("dl")
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.8)

project(test_package C) # if the project is pure C
# project(test_package CXX) # if the project uses c++

find_package(package REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
# don't link to ${CONAN_LIBS} or CONAN_PKG::package
target_link_libraries(${PROJECT_NAME} PRIVATE package::package)
# In case the target project need a specific C++ standard
# target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"

def requirements(self):
self.requires(self.tested_reference_str)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
#include "package/foobar.h" // Make sure includes work as expected


int main(void) {
printf("Create a minimal usage for the target project here.\n");
printf("Avoid big examples, bigger than 100 lines\n");
printf("Avoid networking connections.\n");
printf("Avoid background apps or servers.\n");
printf("The propose is testing the generated artifacts only.\n");

foobar_print_version(); // Make sure to call something that will require linkage for compiled libraries

return EXIT_SUCCESS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.8)

project(test_package C) # if the project is pure C
# project(test_package CXX) # if the project uses c++

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

find_package(package REQUIRED CONFIG)

# Re-use the same source file from test_package folder
add_executable(${PROJECT_NAME} ../test_package/test_package.c)
# don't link to ${CONAN_LIBS} or CONAN_PKG::package
target_link_libraries(${PROJECT_NAME} PRIVATE package::package)
# in case the target project requires a C++ standard
# set_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
File renamed without changes.
29 changes: 29 additions & 0 deletions docs/package_templates/cmake_package/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
sources:
# Newer versions at the top
"1.2.0":
url: [
"https://mirror1.net/package-1.2.0.tar.gz",
"https://mirror2.net/package-1.2.0.tar.gz",
]
sha256: "________________________________________________________________"
"1.1.0":
url: [
"https://mirror1.net/package-1.1.0.tar.gz",
"https://mirror2.net/package-1.1.0.tar.gz",
]
sha256: "________________________________________________________________"
patches:
# Newer versions at the top
"1.1.0":
- patch_file: "patches/0001-fix-cmake.patch"
patch_description: "correct the order of cmake min and project"
patch_type: "backport"
patch_source: "https://github.com/owner/package/pulls/42"
sha256: "________________________________________________________________"
base_path: "source_subfolder"
- patch_file: "patches/0002-fix-linux.patch"
patch_description: "add missing header to support linux"
patch_type: "portability"
patch_source: "https://github.com/owner/package/issues/0"
sha256: "________________________________________________________________"
base_path: "source_subfolder"
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.microsoft import msvc_runtime_flag, is_msvc
from conan.tools.microsoft import is_msvc_static_runtime, is_msvc
from conan.tools.files import apply_conandata_patches, get, copy, rm, rmdir, replace_in_file
from conan.tools.build import check_min_cppstd
from conan.tools.scm import Version
Expand All @@ -18,8 +18,8 @@ class PackageConan(ConanFile):
license = "" # Use short name only, conform to SPDX License List: https://spdx.org/licenses/
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/project/package"
topics = ("topic1", "topic2", "topic3") # no "conan" and project name in topics
settings = "os", "arch", "compiler", "build_type" # even for header only
topics = ("topic1", "topic2", "topic3") # no "conan" and project name in topics
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
Expand All @@ -29,16 +29,6 @@ class PackageConan(ConanFile):
"fPIC": True,
}

# don't use self.settings_build
@property
def _settings_build(self):
return getattr(self, "settings_build", self.settings)

# don't use self.user_info_build
@property
def _user_info_build(self):
return getattr(self, "user_info_build", self.deps_user_info)

@property
def _minimum_cpp_standard(self):
return 17
Expand Down Expand Up @@ -78,34 +68,30 @@ def configure(self):
except Exception:
pass

def layout(self):
cmake_layout(self, src_folder="src") # src_folder must use the same source folder name the project

def requirements(self):
self.requires("dependency/0.8.1") # prefer self.requires method instead of requires attribute

# Only in case the project is header-only
def package_id(self):
self.info.clear()

# if another tool than the compiler or CMake is required to build the project (pkgconf, bison, flex etc)
def build_requirements(self):
self.tool_requires("tool/x.y.z")

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

def validate(self):
# validate the minimum cpp standard supported
# validate the minimum cpp standard supported. For C++ projects only
if self.info.settings.compiler.cppstd:
check_min_cppstd(self, self._minimum_cpp_standard)
minimum_version = self._compilers_minimum_version.get(str(self.info.settings.compiler), False)
if minimum_version and Version(self.info.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(f"{self.name} requires C++{self._minimum_cpp_standard}, which your compiler does not support.")
raise ConanInvalidConfiguration(f"{self.ref} requires C++{self._minimum_cpp_standard}, which your compiler does not support.")
# in case it does not work in another configuration, it should validated here too
if is_msvc(self) and self.info.options.shared:
raise ConanInvalidConfiguration(f"{self.name} can not be built as shared on Visual Studio and msvc.")
raise ConanInvalidConfiguration(f"{self.ref} can not be built as shared on Visual Studio and msvc.")

def layout(self):
cmake_layout(self, src_folder="src") # src_folder must use the same source folder name the project
# if another tool than the compiler or CMake is required to build the project (pkgconf, bison, flex etc)
def build_requirements(self):
self.tool_requires("tool/x.y.z")

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

def generate(self):
# BUILD_SHARED_LIBS and POSITION_INDEPENDENT_CODE are automatically parsed when self.options.shared or self.options.fPIC exist
Expand All @@ -114,7 +100,10 @@ def generate(self):
tc.cache_variables["PACKAGE_CUSTOM_DEFINITION"] = True
if is_msvc(self):
# don't use self.settings.compiler.runtime
tc.cache_variables.definitions["USE_MSVC_RUNTIME_LIBRARY_DLL"] = "MD" in msvc_runtime_flag(self)
tc.cache_variables.definitions["USE_MSVC_RUNTIME_LIBRARY_DLL"] = not is_msvc_static_runtime(self)
# deps_cpp_info, deps_env_info and deps_user_info are no longer used
if self.dependencies["dependency"].options.foobar:
tc.cache_variables["DEPENDENCY_LIBPATH"] = self.dependencies["dependency"].cpp_info.libdirs
tc.generate()
# In case there are dependencies listed on requirements, CMakeDeps should be used
tc = CMakeDeps(self)
Expand All @@ -126,10 +115,10 @@ def generate(self):
def _patch_sources(self):
apply_conandata_patches(self)
# remove bundled xxhash
rm(self, "whateer.*", os.path.join(self._source_subfolder, "lib"))
rm(self, "whateer.*", os.path.join(self.source_folder, "lib"))
replace_in_file(
self,
os.path.join(self._cmakelists_subfolder, "CMakeLists.txt"),
os.path.join(self.source_folder, "CMakeLists.txt"),
"...",
"",
)
Expand All @@ -140,7 +129,7 @@ def build(self):
cmake.build()

def package(self):
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_subfolder)
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
cmake = CMake(self)
cmake.install()

Expand Down
27 changes: 27 additions & 0 deletions docs/package_templates/cmake_package/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os


# It will become the standard on Conan 2.x
class TestPackageConan(ConanFile):
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 can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
Loading

0 comments on commit 29fe03c

Please sign in to comment.