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

[tools] Add system package manger with ncurses as example #177

Merged
merged 23 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d92cc05
Add system package manger with ncurses
uilianries Jan 31, 2025
db363a0
Add entry for system example in docs
uilianries Jan 31, 2025
577947b
Add ci script to validate new example
uilianries Jan 31, 2025
1588288
Use invalid configuration if not linux
uilianries Jan 31, 2025
3874e44
Add consumer application for ncurses
uilianries Jan 31, 2025
249976d
Execute test only on Linux
uilianries Jan 31, 2025
fef2c93
Simplify consumer package
uilianries Jan 31, 2025
b130314
Add support for Macos
uilianries Feb 3, 2025
8818e19
Add support for FreeBSD
uilianries Feb 3, 2025
f4dcb75
Elaborate better example using ncurses
uilianries Feb 3, 2025
4326fc1
Fix exported source file name
uilianries Feb 3, 2025
950af44
Avoid interactive command on CI
uilianries Feb 3, 2025
668cbbd
Simplify consumer example
uilianries Feb 3, 2025
ecf1d3f
Update documentation url for sys reqs example
uilianries Feb 3, 2025
c9325e2
Add support for FreeBSD
uilianries Feb 3, 2025
e8e45a2
Use official CMake target name for Curses
uilianries Feb 3, 2025
8969488
Only run consumer example on supported Os
uilianries Feb 3, 2025
774b34c
Update examples/tools/system/package_manager/consumer/conanfile.py
uilianries Feb 4, 2025
c1d6595
Update examples/tools/system/package_manager/consumer/conanfile.py
uilianries Feb 4, 2025
1e9d1d0
Fix expected curses cmake target name
uilianries Feb 4, 2025
46a4e24
Enforce terminfo for CI
uilianries Feb 4, 2025
e3607c1
Do not run the example app with build
uilianries Feb 4, 2025
240f393
Do not run the example app with build - take 2
uilianries Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@

- Build [ROS packages inside their workspace](ros/rosenv/workspace) using the [fmt library from Conan Center](https://conan.io/center/recipes/fmt) and consuming them also as transitive dependencies.
- Build a [ROS navigation package](ros/rosenv/navigation_ws) that sends goals to a mobile robot from a YAML file using the [yaml-cpp library from Conan Center](https://conan.io/center/recipes/yaml-cpp).

### [tools.system](system)

- Wrap a [system package](system/package_manager/) using Conan and [ncurses](https://invisible-island.net/ncurses/). [Docs](https://docs.conan.io/2/examples/tools/system/package_manager.html)
25 changes: 25 additions & 0 deletions examples/tools/system/package_manager/ci_test_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from test.examples_tools import run
import sys


print("- Packaging system ncurses library using Conan -")

if sys.platform != "linux":
print("INFO: Skipping test, only for Linux due to system requirements.")
sys.exit(0)

confs = ["tools.system.package_manager:mode=install",
"tools.system.package_manager:sudo=true",
"tools.build:verbosity=verbose",
"tools.compilation:verbosity=verbose"]

out = run("conan create . {}".format(" ".join(["-c " + conf for conf in confs])))

assert "ncurses/system: System requirements"
assert "package(): WARN: No files in this package" in out

print("- Consuming Conan package ncurses/system -")

out = run("conan build consumer/ --name=ncurses-version --version=0.1.0 {}".format(" ".join(["-c " + conf for conf in confs])))

assert "The example application has been successfully built" in out
59 changes: 59 additions & 0 deletions examples/tools/system/package_manager/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from conan import ConanFile
from conan.tools.system import package_manager
from conan.tools.gnu import PkgConfig
from conan.errors import ConanInvalidConfiguration

required_conan_version = ">=2.0"


class SysNcursesConan(ConanFile):
name = "ncurses"
version = "system"
description = "A textual user interfaces that work across a wide variety of terminals"
topics = ("curses", "terminal", "toolkit")
homepage = "https://invisible-mirror.net/archives/ncurses/"
license = "MIT"
package_type = "shared-library"
settings = "os", "arch", "compiler", "build_type"

def package_id(self):
self.info.clear()

def validate(self):
supported_os = ["Linux", "Macos", "FreeBSD"]
if self.settings.os not in supported_os:
raise ConanInvalidConfiguration(f"{self.ref} wraps a system package only supported by {supported_os}.")

def system_requirements(self):
dnf = package_manager.Dnf(self)
dnf.install(["ncurses-devel"], update=True, check=True)

yum = package_manager.Yum(self)
yum.install(["ncurses-devel"], update=True, check=True)

apt = package_manager.Apt(self)
apt.install(["libncurses-dev"], update=True, check=True)

pacman = package_manager.PacMan(self)
pacman.install(["ncurses"], update=True, check=True)

zypper = package_manager.Zypper(self)
zypper.install(["ncurses"], update=True, check=True)

brew = package_manager.Brew(self)
brew.install(["ncurses"], update=True, check=True)

pkg = package_manager.Pkg(self)
pkg.install(["ncurses"], update=True, check=True)

def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []

self.cpp_info.set_property("cmake_file_name", "Curses")
self.cpp_info.set_property("cmake_target_name", "Curses::Curses")
self.cpp_info.set_property("cmake_additional_variables_prefixes", ["CURSES",])

pkg_config = PkgConfig(self, 'ncurses')
pkg_config.fill_cpp_info(self.cpp_info, is_system=True)
9 changes: 9 additions & 0 deletions examples/tools/system/package_manager/consumer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.15)
project(ncurses_version C)

find_package(Curses CONFIG REQUIRED)

add_executable(${PROJECT_NAME} ncurses_version.c)
target_link_libraries(${PROJECT_NAME} PRIVATE Curses::Curses)

install(TARGETS ${PROJECT_NAME} DESTINATION bin)
26 changes: 26 additions & 0 deletions examples/tools/system/package_manager/consumer/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os


class AppNCursesVersionConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain"
package_type = "application"
exports_sources = "CMakeLists.txt", "ncurses_version.c"

def requirements(self):
if self.settings.os in ["Linux", "Macos", "FreeBSD"]:
self.requires("ncurses/system")

def layout(self):
cmake_layout(self)

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

app_path = os.path.join(self.build_folder, "ncurses_version")
self.output.info(f"The example application has been successfully built.\nPlease run the executable using: '{app_path}'")
26 changes: 26 additions & 0 deletions examples/tools/system/package_manager/consumer/ncurses_version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <ncurses.h>


int main(void) {
int max_y, max_x;
char message [256] = {0};

initscr();

start_color();
init_pair(1, COLOR_BLUE, COLOR_WHITE);
getmaxyx(stdscr, max_y, max_x);

snprintf(message, sizeof(message), "Conan 2.x Examples - Installed ncurses version: %s\n", curses_version());
attron(COLOR_PAIR(1));
mvprintw(max_y / 2, max_x / 2 - (strlen(message) / 2), "%s", message);
attroff(COLOR_PAIR(1));

refresh();

return EXIT_SUCCESS;
}