Skip to content

Commit 584592a

Browse files
committed
Build Requires Example
1 parent 6724a5d commit 584592a

File tree

5 files changed

+134
-9
lines changed

5 files changed

+134
-9
lines changed
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
cmake_minimum_required(VERSION 3.24)
22

3-
project(FormatOutput LANGUAGES CXX C)
3+
project(BuildRequiresExample LANGUAGES CXX)
44

5-
set(CMAKE_CXX_STANDARD 14)
5+
set(CMAKE_CXX_STANDARD 17)
6+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
67

7-
find_package(fmt REQUIRED)
8+
# Find the abseil package (provided by CMakeDeps generator)
9+
find_package(absl REQUIRED)
810

11+
# Create the executable
912
add_executable(main main.cpp)
10-
target_link_libraries(main PRIVATE fmt::fmt)
13+
14+
# Link against abseil libraries
15+
target_link_libraries(main PRIVATE
16+
absl::strings
17+
absl::str_format
18+
absl::base
19+
)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""Conan recipe demonstrating tool_requires with CMake and abseil dependency.
2+
3+
This example shows how to use tool_requires to specify build-time dependencies
4+
like CMake, while using regular requires for runtime dependencies like abseil.
5+
"""
6+
7+
from conan import ConanFile
8+
from conan.tools.cmake import CMake, cmake_layout
9+
10+
11+
class BuildRequiresExample(ConanFile):
12+
"""Example Conan recipe demonstrating tool_requires with CMake and abseil."""
13+
14+
name = 'build_requires_example'
15+
version = '1.0'
16+
17+
# Basic package configuration
18+
settings = 'os', 'compiler', 'build_type', 'arch'
19+
20+
# Regular dependencies - libraries we link against
21+
requires = 'abseil/20240116.2'
22+
23+
# Build dependencies - tools needed during build
24+
tool_requires = 'cmake/[>=3.24]'
25+
26+
# Generators for CMake integration
27+
generators = 'CMakeToolchain', 'CMakeDeps'
28+
29+
def layout(self):
30+
"""Define the layout for the project."""
31+
cmake_layout(self)
32+
33+
def configure(self):
34+
"""Configure package options based on settings."""
35+
# Example: Configure abseil options if needed
36+
# self.options["abseil"].shared = False
37+
pass
38+
39+
def build_requirements(self):
40+
"""Additional build requirements logic if needed."""
41+
# This method can be used for conditional build requirements
42+
# For example, only require certain tools on specific platforms
43+
pass
44+
45+
def build(self):
46+
"""Build the project using CMake."""
47+
cmake = CMake(self)
48+
cmake.configure()
49+
cmake.build()
50+
51+
def package(self):
52+
"""Package the built artifacts."""
53+
cmake = CMake(self)
54+
cmake.install()
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1-
#include "fmt/color.h"
1+
#include <iostream>
2+
#include "absl/strings/str_format.h"
3+
#include "absl/strings/string_view.h"
4+
#include "absl/base/macros.h"
25

36
int main()
47
{
5-
fmt::print(fg(fmt::terminal_color::cyan), "Hello fmt {}!\n", FMT_VERSION);
8+
// Demonstrate abseil string formatting
9+
absl::string_view greeting = "Hello";
10+
std::string name = "Abseil";
11+
12+
// Use absl::StrFormat instead of printf-style formatting
13+
std::string formatted = absl::StrFormat("%s %s! Version: %s",
14+
greeting, name,
15+
ABSL_PACKAGE_VERSION);
16+
17+
std::cout << formatted << std::endl;
18+
19+
// Demonstrate some abseil string operations
20+
std::string message = absl::StrFormat("This example shows tool_requires with CMake %s",
21+
"working correctly!");
22+
std::cout << message << std::endl;
23+
624
return 0;
725
}

examples/conan_cmake/build_requires/pyproject.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
2-
description = "A simple project showing how to use conan with CPPython"
3-
name = "cppython-conan-cmake-simple"
2+
description = "Example showing tool_requires with CMake and abseil dependency"
3+
name = "cppython-conan-cmake-build-requires"
44
version = "1.0.0"
55

66
license = { text = "MIT" }
@@ -18,7 +18,11 @@ provider-name = "conan"
1818

1919
install-path = "install"
2020

21-
dependencies = ["fmt>=11.2.0"]
21+
dependencies = ["abseil/20240116.2"]
22+
23+
# Future tool_requires support (not yet implemented in CPPython):
24+
# [tool.cppython.provider.tool_requires]
25+
# cmake = ">=3.20"
2226

2327
[tool.cppython.generator]
2428

tests/integration/examples/test_conan_cmake.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,43 @@ def test_simple(example_runner: CliRunner) -> None:
5959

6060
# Publish the project to the local cache
6161
publish_project.publish()
62+
63+
@staticmethod
64+
def test_build_requires(example_runner: CliRunner) -> None:
65+
"""build_requires project"""
66+
# Create project configuration
67+
project_root = Path.cwd()
68+
project_configuration = ProjectConfiguration(project_root=project_root, version=None, verbosity=2, debug=True)
69+
70+
# Create console interface
71+
interface = ConsoleInterface()
72+
73+
# Load pyproject.toml data
74+
pyproject_path = project_root / 'pyproject.toml'
75+
pyproject_data = loads(pyproject_path.read_text(encoding='utf-8'))
76+
77+
# Create and use the project directly
78+
project = Project(project_configuration, interface, pyproject_data)
79+
80+
# Call install directly to get structured results
81+
project.install()
82+
83+
# Run the CMake configuration command
84+
result = subprocess.run(['cmake', '--preset=default'], capture_output=True, text=True, check=False)
85+
86+
assert result.returncode == 0, f'Cmake failed: {result.stderr}'
87+
88+
path = Path('build').absolute()
89+
90+
# Verify that the build directory contains the expected files
91+
assert (path / 'CMakeCache.txt').exists(), f'{path / "CMakeCache.txt"} not found'
92+
93+
# --- Setup for Publish with modified config ---
94+
# Modify the in-memory representation of the pyproject data
95+
pyproject_data['tool']['cppython']['provider']['remotes'] = []
96+
97+
# Create a new project instance with the modified configuration for the 'publish' step
98+
publish_project = Project(project_configuration, interface, pyproject_data)
99+
100+
# Publish the project to the local cache
101+
publish_project.publish()

0 commit comments

Comments
 (0)