Skip to content

Commit c9e7c6e

Browse files
authored
(#12851) [docs] header-only package template
* Add header-only template Signed-off-by: Uilian Ries <[email protected]> * Missing self Signed-off-by: Uilian Ries <[email protected]>
1 parent 782262c commit c9e7c6e

File tree

8 files changed

+239
-0
lines changed

8 files changed

+239
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
sources:
2+
# Newer versions at the top
3+
"1.2.0":
4+
url: [
5+
"https://mirror1.net/package-1.2.0.tar.gz",
6+
"https://mirror2.net/package-1.2.0.tar.gz",
7+
]
8+
sha256: "________________________________________________________________"
9+
"1.1.0":
10+
url: [
11+
"https://mirror1.net/package-1.1.0.tar.gz",
12+
"https://mirror2.net/package-1.1.0.tar.gz",
13+
]
14+
sha256: "________________________________________________________________"
15+
patches:
16+
# Newer versions at the top
17+
"1.1.0":
18+
- patch_file: "patches/0001-fix-cmake.patch"
19+
patch_description: "correct the order of cmake min and project"
20+
patch_type: "backport"
21+
patch_source: "https://github.com/owner/package/pulls/42"
22+
sha256: "________________________________________________________________"
23+
base_path: "source_subfolder"
24+
- patch_file: "patches/0002-fix-linux.patch"
25+
patch_description: "add missing header to support linux"
26+
patch_type: "portability"
27+
patch_source: "https://github.com/owner/package/issues/0"
28+
sha256: "________________________________________________________________"
29+
base_path: "source_subfolder"
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from conan import ConanFile
2+
from conan.errors import ConanInvalidConfiguration
3+
from conan.tools.files import apply_conandata_patches, get, copy
4+
from conan.tools.build import check_min_cppstd
5+
from conan.tools.scm import Version
6+
from conan.tools.layout import basic_layout
7+
import os
8+
9+
10+
required_conan_version = ">=1.51.3"
11+
12+
13+
class PackageConan(ConanFile):
14+
name = "package"
15+
description = "short description"
16+
license = "" # Use short name only, conform to SPDX License List: https://spdx.org/licenses/
17+
url = "https://github.com/conan-io/conan-center-index"
18+
homepage = "https://github.com/project/package"
19+
topics = ("topic1", "topic2", "topic3", "header-only") # no "conan" and project name in topics, keep 'header-only'
20+
settings = "os", "arch", "compiler", "build_type" # even for header only
21+
no_copy_source = True # do not copy sources to build folder for header only projects, unless, need to apply patches
22+
23+
@property
24+
def _minimum_cpp_standard(self):
25+
return 14
26+
27+
# in case the project requires C++14/17/20/... the minimum compiler version should be listed
28+
@property
29+
def _compilers_minimum_version(self):
30+
return {
31+
"Visual Studio": "15",
32+
"msvc": "14.1",
33+
"gcc": "5",
34+
"clang": "5",
35+
"apple-clang": "5.1",
36+
}
37+
38+
# no exports_sources attribute, but export_sources(self) method instead
39+
# this allows finer grain exportation of patches per version
40+
def export_sources(self):
41+
for p in self.conan_data.get("patches", {}).get(self.version, []):
42+
copy(self, p["patch_file"], self.recipe_folder, self.export_sources_folder)
43+
44+
def layout(self):
45+
# src_folder must use the same source folder name the project
46+
basic_layout(self, src_folder="src")
47+
48+
def requirements(self):
49+
# prefer self.requires method instead of requires attribute
50+
self.requires("dependency/0.8.1")
51+
52+
# same package ID for any package
53+
def package_id(self):
54+
self.info.clear()
55+
56+
def validate(self):
57+
# compiler subsettings are not available when building with self.info.clear()
58+
if self.info.settings.get_safe("compiler.cppstd"):
59+
# validate the minimum cpp standard supported when installing the package. For C++ projects only
60+
check_min_cppstd(self, self._minimum_cpp_standard)
61+
minimum_version = self._compilers_minimum_version.get(str(self.info.settings.compiler), False)
62+
if minimum_version and Version(self.info.settings.get_safe("compiler.version")) < minimum_version:
63+
raise ConanInvalidConfiguration(f"{self.ref} requires C++{self._minimum_cpp_standard}, which your compiler does not support.")
64+
# in case it does not work in another configuration, it should validated here too
65+
if self.info.settings.os == "Windows":
66+
raise ConanInvalidConfiguration(f"{self.ref} can not be used on Windows.")
67+
68+
# if another tool than the compiler or CMake is required to build the project (pkgconf, bison, flex etc)
69+
def build_requirements(self):
70+
self.tool_requires("tool/x.y.z")
71+
72+
def source(self):
73+
# download source package and extract to source folder
74+
get(self, **self.conan_data["sources"][self.version],
75+
destination=self.source_folder, strip_root=True)
76+
77+
# not mandatory when there is no patch, but will suppress warning message about missing build() method
78+
def build(self):
79+
# The attribute no_copy_source should not be used when applying patches in build
80+
apply_conandata_patches(self)
81+
82+
# copy all files to the package folder
83+
def package(self):
84+
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
85+
copy(self, pattern="*.h", dst=os.path.join(self.package_folder, "include"), src=os.path.join(self.source_folder, "include"))
86+
87+
def package_info(self):
88+
# folders not used for header-only
89+
self.cpp_info.bindirs = []
90+
self.cpp_info.frameworkdirs = []
91+
self.cpp_info.libdirs = []
92+
self.cpp_info.resdirs = []
93+
94+
# if package has an official FindPACKAGE.cmake listed in https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#find-modules
95+
# examples: bzip2, freetype, gdal, icu, libcurl, libjpeg, libpng, libtiff, openssl, sqlite3, zlib...
96+
self.cpp_info.set_property("cmake_module_file_name", "PACKAGE")
97+
self.cpp_info.set_property("cmake_module_target_name", "PACKAGE::PACKAGE")
98+
# if package provides a CMake config file (package-config.cmake or packageConfig.cmake, with package::package target, usually installed in <prefix>/lib/cmake/<package>/)
99+
self.cpp_info.set_property("cmake_file_name", "package")
100+
self.cpp_info.set_property("cmake_target_name", "package::package")
101+
# if package provides a pkgconfig file (package.pc, usually installed in <prefix>/lib/pkgconfig/)
102+
self.cpp_info.set_property("pkg_config_name", "package")
103+
104+
# If they are needed on Linux, m, pthread and dl are usually needed on FreeBSD too
105+
if self.settings.os in ["Linux", "FreeBSD"]:
106+
self.cpp_info.system_libs.append("m")
107+
self.cpp_info.system_libs.append("pthread")
108+
self.cpp_info.system_libs.append("dl")
109+
110+
# TODO: to remove in conan v2 once cmake_find_package_* generators removed
111+
self.cpp_info.filenames["cmake_find_package"] = "PACKAGE"
112+
self.cpp_info.filenames["cmake_find_package_multi"] = "package"
113+
self.cpp_info.names["cmake_find_package"] = "PACKAGE"
114+
self.cpp_info.names["cmake_find_package_multi"] = "package"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
3+
project(test_package C) # if the project is pure C
4+
project(test_package CXX) # if the project uses c++
5+
6+
find_package(package REQUIRED CONFIG)
7+
8+
add_executable(${PROJECT_NAME} test_package.cpp)
9+
# don't link to ${CONAN_LIBS} or CONAN_PKG::package
10+
target_link_libraries(${PROJECT_NAME} PRIVATE package::package)
11+
# In case the target project need a specific C++ standard
12+
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from conan import ConanFile
2+
from conan.tools.build import can_run
3+
from conan.tools.cmake import cmake_layout, CMake
4+
import os
5+
6+
7+
# It will become the standard on Conan 2.x
8+
class TestPackageConan(ConanFile):
9+
settings = "os", "arch", "compiler", "build_type"
10+
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
11+
test_type = "explicit"
12+
13+
def requirements(self):
14+
self.requires(self.tested_reference_str)
15+
16+
def layout(self):
17+
cmake_layout(self)
18+
19+
def build(self):
20+
cmake = CMake(self)
21+
cmake.configure()
22+
cmake.build()
23+
24+
def test(self):
25+
if can_run(self):
26+
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
27+
self.run(bin_path, env="conanrun")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <cstdlib>
2+
#include <iostream>
3+
#include "package/foobar.hpp"
4+
5+
6+
int main(void) {
7+
std::cout << "Create a minimal usage for the target project here." << std::endl;
8+
std::cout << "Avoid big examples, bigger than 100 lines" << std::endl;
9+
std::cout << "Avoid networking connections." << std::endl;
10+
std::cout << "Avoid background apps or servers." << std::endl;
11+
std::cout << "The propose is testing the generated artifacts only." << std::endl;
12+
13+
foobar.print_version();
14+
15+
return EXIT_SUCCESS;
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
3+
project(test_package C) # if the project is pure C
4+
project(test_package CXX) # if the project uses c++
5+
6+
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
7+
conan_basic_setup(TARGETS)
8+
9+
find_package(package REQUIRED CONFIG)
10+
11+
# Re-use the same source file from test_package folder
12+
add_executable(${PROJECT_NAME} ../test_package/test_package.cpp)
13+
# don't link to ${CONAN_LIBS} or CONAN_PKG::package
14+
target_link_libraries(${PROJECT_NAME} PRIVATE package::package)
15+
# in case the target project requires a C++ standard
16+
set_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from conans import ConanFile, CMake
2+
from conan.tools.build import cross_building
3+
import os
4+
5+
6+
# legacy validation with Conan 1.x
7+
class TestPackageV1Conan(ConanFile):
8+
settings = "os", "arch", "compiler", "build_type"
9+
generators = "cmake", "cmake_find_package_multi"
10+
11+
def build(self):
12+
cmake = CMake(self)
13+
cmake.configure()
14+
cmake.build()
15+
16+
def test(self):
17+
if not cross_building(self):
18+
bin_path = os.path.join("bin", "test_package")
19+
self.run(bin_path, run_environment=True)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
versions:
2+
# Newer versions at the top
3+
"1.2.0":
4+
folder: all
5+
"1.1.0":
6+
folder: all

0 commit comments

Comments
 (0)