Skip to content

Commit

Permalink
[tools] Add system package manger with ncurses as example (#177)
Browse files Browse the repository at this point in the history
* Add system package manger with ncurses

Signed-off-by: Uilian Ries <[email protected]>

* Add entry for system example in docs

Signed-off-by: Uilian Ries <[email protected]>

* Add ci script to validate new example

Signed-off-by: Uilian Ries <[email protected]>

* Use invalid configuration if not linux

Signed-off-by: Uilian Ries <[email protected]>

* Add consumer application for ncurses

Signed-off-by: Uilian Ries <[email protected]>

* Execute test only on Linux

Signed-off-by: Uilian Ries <[email protected]>

* Simplify consumer package

Signed-off-by: Uilian Ries <[email protected]>

* Add support for Macos

Signed-off-by: Uilian Ries <[email protected]>

* Add support for FreeBSD

Signed-off-by: Uilian Ries <[email protected]>

* Elaborate better example using ncurses

Signed-off-by: Uilian Ries <[email protected]>

* Fix exported source file name

Signed-off-by: Uilian Ries <[email protected]>

* Avoid interactive command on CI

Signed-off-by: Uilian Ries <[email protected]>

* Simplify consumer example

Signed-off-by: Uilian Ries <[email protected]>

* Update documentation url for sys reqs example

Signed-off-by: Uilian Ries <[email protected]>

* Add support for FreeBSD

Signed-off-by: Uilian Ries <[email protected]>

* Use official CMake target name for Curses

Signed-off-by: Uilian Ries <[email protected]>

* Only run consumer example on supported Os

Signed-off-by: Uilian Ries <[email protected]>

* Update examples/tools/system/package_manager/consumer/conanfile.py

Co-authored-by: Carlos Zoido <[email protected]>

* Update examples/tools/system/package_manager/consumer/conanfile.py

Co-authored-by: Carlos Zoido <[email protected]>

* Fix expected curses cmake target name

Signed-off-by: Uilian Ries <[email protected]>

* Enforce terminfo for CI

Signed-off-by: Uilian Ries <[email protected]>

* Do not run the example app with build

Signed-off-by: Uilian Ries <[email protected]>

* Do not run the example app with build - take 2

Signed-off-by: Uilian Ries <[email protected]>

---------

Signed-off-by: Uilian Ries <[email protected]>
Co-authored-by: Carlos Zoido <[email protected]>
  • Loading branch information
uilianries and czoido authored Feb 4, 2025
1 parent a1fac4b commit b8122ad
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 0 deletions.
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;
}

0 comments on commit b8122ad

Please sign in to comment.