conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.17k stars 974 forks source link

[suggestion] Having os=None would be awesome for bare metal cross compilation #4216

Closed pepe82sh closed 2 years ago

pepe82sh commented 5 years ago

To help us debug your issue please explain:

Currently there is no option for having no OS. I'm playing with cross compilation in a bare metal environment, and it'd be great to have "None" as an option. I am aware that I can provide my own settings.yml, yet I think it could be a nice option for the rest of the world.

memsharded commented 5 years ago

There is a "small" issue to be considered: providing a value "None" as possible, allows that setting not to be defined, which could have wildly unintended effects. Now, users that by mistake do not provide a value for the settings.os for recipes with settings = "os", ... quickly get an error, telling them to provide it. If None was added, that will fail, and the build will fail later, maybe with a less clear error message.

Not saying that it can't be added, but the truth is that for bare-metal users are going to need to provide their own settings.yml anyway.

pepe82sh commented 5 years ago

I understand your point at this matter. I created/forked a arm-none-eabi-gcc package where I thought of limiting the os setting to bare metal, yet I don't want to introduce non standard settings at that point. Right now I just ignore that setting, which should work okay as well. Thanks!

DavidZemon commented 5 years ago

Can you re-open this?

As a workaround for #4382 , I created an OS in my local settings.yml with an OS of type "None" (as in, the string value "None"). I then check if the OS is equal to "None" and act accordingly based on that. However, the recipe fails to build in Travis for any OS simply because I'm comparing to a non-existent OS. See my pull request here and one of the failing builds here.

lasote commented 5 years ago

When you specify the None value in the settings.yml file it doesn't mean that you can specify the "None" value as a setting, it means that you can avoid specifying it (not using os=XXX in the profile or in the -s). Then you can check if not self.settings.os:

DavidZemon commented 5 years ago

Ah, thank you! I did not realize Conan treated "None" specially. That makes a lot more sense and does, in fact, make my life much easier. I do wish you'd add None into the default settings.yml file though.

lasote commented 5 years ago

As memsharded said, it would enable mistakes when the os is not specified. Only for embedded and some other special cases, the None makes sense. We really encourage the users to use the conan config install and distribute the settings.yml and any other config that way. Anyway, happy it works for you!

jhol commented 5 years ago

I just encountered this issue myself - before encountering this Issue.

I made my own patch which adds None as an option for os and os_target:

From 5ced9dae789853b0b3393afc5fdb9ff614ed73fc Mon Sep 17 00:00:00 2001
From: Joel Holdsworth <joel.holdsworth@vcatechnology.com>
Date: Mon, 3 Jun 2019 16:03:07 +0100
Subject: [PATCH] Added "None" os

---
 conans/client/conf/__init__.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index 2bdddf83..6f76edb7 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -18,7 +18,7 @@ arch_build: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv

 # Only for building cross compilation tools, 'os_target/arch_target' is the system for
 # which the tools generate code
-os_target: [Windows, Linux, Macos, Android, iOS, watchOS, tvOS, FreeBSD, SunOS, AIX, Arduino, Neutrino]
+os_target: [Windows, Linux, Macos, Android, iOS, watchOS, tvOS, FreeBSD, SunOS, AIX, Arduino, Neutrino, None]
 arch_target: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le]

 # Rest of the settings are "host" settings:
@@ -51,6 +51,7 @@ os:
     Emscripten:
     Neutrino:
         version: ["6.4", "6.5", "6.6", "7.0"]
+    None:
 arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le]
 compiler:
     sun-cc:
-- 
2.20.1

With this change, I was able to make a functioning conan recipe for libopencm3, so does it need to be any more complicated? I didn't seem to need a non-standard settings.yml.

If None cannot be used, could we have Bare or something similar instead?

lasote commented 5 years ago

I still think that it shouldn't be introduced for the general purpose, I understand and agree it is nice in some cases, but only to support that cases you open the door to mistakes for the 99% of user. @jhol you can share/store your settings.yml with conan config install command.

jhol commented 5 years ago

What about Bare then? Much less chance of the user getting mixed up with that one.

lasote commented 5 years ago

Still confusing, because you typically want in that case of bare metal to not specify "os" in your recipe settings field.

jwillikers commented 3 years ago

@lasote What about cases where a package can be used in both embedded and non-embedded contexts, i.e. fmt? Surely we shouldn't remove the os option from the fmt recipe?

memsharded commented 3 years ago

I am starting to think that having a root identifier "bare" for not-OS systems, could be useful. Users could further add sub-settings to represent different bare metal systems (boards, micros, etc), but "bare" could be a useful convention.

Re-opening to discuss.

jwillikers commented 3 years ago

Yeah, this would be a very helpful convention. At my company, we're currently looking at organizing this with just the bare OS setting and then using options specific to the board / RTOS in the Conanfile of the package that builds the embedded executable. This seems pretty convenient for configuring any particular HAL / RTOS that are Conan packages, since they can be entirely controlled / configured through package-level options. We think we might be able to avoid having to add any sub-options to the settings file using this approach.

msduketown commented 2 years ago

Why not rename bare to posix®?

Some projects use generic, but that's a bit too detached from formalization, to my tasting. Also, posix implies back and forward compatibility through the deterministic UTF8format.

johnmcfarlane commented 2 years ago

I also need to build/package for systems with no OS... and I cannot resist a good discuss!

I don't know how the default is being propagated but it sounds as if None is being misused here somewhere. Absence of an OS should not be confused with absence of a choice of OS. Similarly, absence of a value in a map should not be confused with a None value in a map.

How it should be represented:

How it maybe is currently:

I can easily believe that fixing this would break recipes and scripts in the field if such a mapping is already exposed to the user. Also, if 'os' is forced to be a parameter somewhere, it's unfortunate that None is then confused with absence of a parameter. Nevertheless, None is the correct way to name the OS available on bare metal systems: other systems have some OS; bare metal systems have none.

If we're stuck with the status quo, and if a 'non-OS' needs to be named, can I vote for freestanding, as in: settings = { 'os': 'freestanding' }? This is the term used in the C++ spec.

johnmcfarlane commented 2 years ago

Why not rename bare to posix®?

Some projects use generic, but that's a bit too detached from formalization, to my tasting. Also, posix implies back and forward compatibility through the deterministic UTF8format.

@msduketown POSIX and bare metal are quite different things to my mind. POSIX is a standard for UNIX-like OSes, whereas bare metal means no OS at all.

redradist commented 2 years ago

Agree with @pepe82sh

Actually there are following use-cases during work with embedded devices: 1) No os, custom task scheduler; any arch 2) RTOS os (FreeRTOS, Zephyr and etc.); any arch

What I do not understand is that why this feature is not implemented ? No os is very common in embedded and question to use RTOS or not depend on application

memsharded commented 2 years ago

Lets add os = bare

johnmcfarlane commented 2 years ago

Bare would work but is unlikely the most accurate term, deriving from 'bare metal'.

Bare metal is (arguably) colloquial and (definitely) ambiguous, referring to an operating system by name, computer systems running operating systems, and non-virtualized hardware with/without an OS.

While less familiar, 'freestanding' is the chosen term in both C and C++ standards. As a self-described "C/C++ Package Manager", would following domain nomenclature be worth further consideration?

@ben-craig thoughts?

memsharded commented 2 years ago

I don't dislike the idea (https://en.cppreference.com/w/cpp/freestanding), but on the other hand I am afraid that this might be slightly confusing for users, if a stronger than expected parallelism is established between this Conan "freestanding" setting and the C and C++ standards, because up to my knowledge "embedded" or "bare metal" developers don't seem to use that term when they refer to their targets and compilers. Some examples:

johnmcfarlane commented 2 years ago

Does the os=freestanding imply the automatic definition by Conan of __STDC_HOSTED__ in C++11 and above compilers? And what about C?

Whether Conan manages this is a good question. I would attempt to answer separately from the question of what name to use in the settings though. Note that freestanding support is less than ideal in C++ historically - hence all the work to improve the situation in papers here.

Does this means that this os=freestanding cannot be used with my embedded cross-compiler to arm, which happens to be gcc 4.4 based and pre C++11?

I really don't know how well that toolchain supports freestanding systems. I suspect it's more a case of providing 'conforming' or 'official' support - rather than support per se.

Can I use header if my cross compiler is c++11 and not c++20 with os=freestanding?

Yeah, that's not a question I would have expected. <bit> arrived in C++20. I would add though that freestanding mostly mandates a minimal set of components and features necessary for conformance in freestanding mode. If an implementation is able to provide a feature marked as hosted in the freestanding mode, I don't think that necessarily means it's not conforming.

E.g. in freestanding mode there might be a main function in a program, but there might not. But in hosted mode, there must be a main function.

Is this setting good for things like Arduino (it is a current setting we would like to move under this umbrella)?

I've no knowledge of that platform. But it looks like Arduino offers both freestanding and hosted options. I would have assumed that Xinu was the OS there - just as (Raspbian) Linux is probably the most common RPi OS.

jwillikers commented 2 years ago

@johnmcfarlane As much as I'm supporting the freestanding proposals, it's probably not as familiar a name and could get caught-up in standardese. Wikipedia has a Bare machine page, which points to the popularity of the term for this context, and Rust uses the Bare Metal terminology: https://docs.rust-embedded.org/book/intro/no-std.html#bare-metal-environments. I think the potential ambiguity for the os setting is acceptable and adding a comment in the default settings.yml should suffice to clarify the intent.

redradist commented 2 years ago

I also prefer bare metal more than freestanding as more known terminology, first I've heard freestanding 1 year ago, though I working with embedded devices long enoght

Quuxplusone commented 2 years ago

I'll jump into the bikeshed to say that os=baremetal would be strictly better (IMO) than os=bare. The phrase everyone (keeps saying they're) familiar with is "bare metal," which implies two good things to me:

os: freestanding strikes me as worse. I'm vaguely familiar with the C++ "freestanding" proposals, and even so, I'd have to go look up whether an RTOS counts as "hosted" or "freestanding" or "it depends." Whereas the phrase "bare metal" definitely 100% means "not even an RTOS," so assuming you're looking for a word that means "not even an RTOS," well, "bare metal" gets the point across clearer.

ben-craig commented 2 years ago

Guess I'll chime in.

An OS target named freestanding wouldn't be a disaster, but baremetal is probably better.

My freestanding papers are targeting 3.5 audiences, and largely excluding a nearby 4th. Looking at those use cases can help inform what makes sense on the package management side of things.

  1. microcontrollers (this closely matches "baremetal")
  2. a. OS kernels (this can also be "baremetal" if you squint)
  3. b. Drivers for someone else's OS kernel, like a Windows, Linux, or OSX kernel driver. (probably not "baremetal", because you care very much about which OS you are plugging into)
  4. GPUs (unlikely that "baremetal" makes sense here, but I'm no GPU expert)
  5. (Excluded) FPGAs, like Xilinx's high level synthesis. Maybe "baremetal" works here until there's a larger ecosystem, including an OS.

I'd have to go look up whether an RTOS counts as "hosted" or "freestanding" or "it depends." Whereas the phrase "bare metal" definitely 100% means "not even an RTOS," so assuming you're looking for a word that means "not even an RTOS," well, "bare metal" gets the point across clearer.

I'm not sure that "bare metal" helps here unfortunately, but I don't really know anything about Conan in these regards. I can imagine a freestanding / bare metal library that is suitable for use with OpenRTOS, threadx, or no OS at all, all supported with the same static library. I can also imagine libraries that take advantage of OpenRTOS features, and wanting to classify those via an OS. I don't know if a consuming client in Conan can say they want libraries that support OpenRTOS (when available) or bare metal (as a fallback).

memsharded commented 2 years ago

Thanks @ben-craig and @johnmcfarlane for the helpful discussion.

Then, given all the feedback, I think the less bad alternative (there is clearly no perfect one for everyone), would be baremetal. There are open questions like the OpenRTOS, which I see becoming its own OS to allow those packages that needs to be aware and are completely specific to OpenRTOS and will not work in other platforms.

Conan does not have a generic binary compatibility model (does this even exists? :) ), but it is always possible to specify the configuration for different packages like -s pkg1:os=openrtos -s pkg2:os=baremetal

I think that it is likely that the community will continue to evolve the settings, possibly creating sub-settings inside baremetal for different platforms, lets see how it goes, lets start with this os=baremetal that seems to be useful for a bunch of Conan users out there today, and we will continue to move from there.

grafikrobot commented 2 years ago

My suggestion would be bare instead of baremetal.

jwillikers commented 2 years ago

@memsharded Thanks for adding the baremetal setting, I'm really excited by this development. Does some sort of translation need to happen in the CMakeToolchain generator in order to default CMAKE_SYSTEM_PLATFORM to Generic when the os is baremetal?