jaulib v1.3.0
Jau Support Library (C++, Java, ..)
os_support.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Gothel Software e.K.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#ifndef JAU_OS_SUPPORT_HPP_
26#define JAU_OS_SUPPORT_HPP_
27
28#include <cstdint>
29
30#include <jau/byte_util.hpp>
31#include <jau/int_types.hpp>
32#include "jau/cpp_lang_util.hpp"
33#include "jau/cpuid.hpp"
34
35namespace jau::os {
36
37 /** @defgroup OSSup OS Support
38 * OS Support Functionality
39 *
40 * Available predefined macros denoting the [Operating Systems](https://sourceforge.net/p/predef/wiki/OperatingSystems/)
41 * - `__FreeBSD__` : FreeBSD
42 * - `__linux__` : Linux, w/o Android: `__linux__ && !__ANDROID__`
43 * - `__ANDROID__` : Android, implies `__linux__`
44 * - `_WIN32` : Windows
45 * - `_WIN64` : Windows 64 bit, implies `_WIN32`
46 * - `__APPLE__` : Darwin, i.e. MacOS or iOS
47 * - `__ros__` : Akaros
48 * - `__native_client__`: NaCL
49 * - `__asmjs__` : AsmJS
50 * - `__EMSCRIPTEN__` : emscripten for asm.js and WebAssembly
51 * - `__Fuchsia__` : Fuchsia
52 *
53 * Further infos:
54 * - [Unix standards](https://sourceforge.net/p/predef/wiki/Standards/)
55 * - [GNU glibc](https://sourceforge.net/p/predef/wiki/Libraries/)
56 * - [glibc 1.3.4 Feature Test Macros](https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html)
57 * - [Architectures](https://sourceforge.net/p/predef/wiki/Architectures/)
58 *
59 * @{
60 */
61
62 namespace impl {
63 constexpr uint32_t get_host_os_id() noexcept {
64 #if defined(__EMSCRIPTEN__)
65 #define JAU_OS_TYPE_UNIX 1
66 #define JAU_OS_TYPE_WASM 1
67 return 0b00000001000000000000000000000001U; // Emscripten
68 #elif defined(__QNXNTO__)
69 #define JAU_OS_TYPE_UNIX 1
70 #define JAU_OS_TYPE_QNXNTO 1
71 return 0b00000000000000000001000000000001U; // QnxNTO
72 #elif defined(__APPLE__) && defined(__MACH__)
73 #define JAU_OS_TYPE_UNIX 1
74 #define JAU_OS_TYPE_DARWIN 1
75 return 0b00000000000000000000100000000001U; // Darwin
76 #elif defined(__FreeBSD__)
77 #define JAU_OS_TYPE_UNIX 1
78 #define JAU_OS_TYPE_FREEBSD 1
79 return 0b00000000000000000000010000000001U; // FreeBSD
80 #elif defined(__ANDROID__)
81 #define JAU_OS_TYPE_UNIX 1
82 #define JAU_OS_TYPE_ANDROID 1
83 return 0b00000000000000000000001100000001U; // Android
84 #elif defined(__linux__)
85 #define JAU_OS_TYPE_UNIX 1
86 #define JAU_OS_TYPE_LINUX 1
87 return 0b00000000000000000000000100000001U; // Linux
88 #elif defined(_WIN32)
89 #define JAU_OS_TYPE_WINDOWS 1
90 return 0b00000000000000000000000000000010U; // Windows
91 #else
92 #define JAU_OS_TYPE_UNIX 1
93 return 0b00000000000000000000000000000001U; // Unix
94 #endif
95 }
96 }
97
98 /** OS type bits and unique IDs */
99 enum class os_type_t : uint32_t {
100 /** Unix bit, contained by: linux, android, freebsd, darwin. */
101 Unix = 0b00000000000000000000000000000001U,
102 /** Windows bit */
103 Windows = 0b00000000000000000000000000000010U,
104 /** Linux bit, contained by: android; includes: unix */
105 Linux = 0b00000000000000000000000100000001U,
106 /** Android bit, includes: linux and unix */
107 Android = 0b00000000000000000000001100000001U,
108 /** FreeBSD bit, includes: unix */
109 FreeBSD = 0b00000000000000000000010000000001U,
110 /** Darwin (Apple OSX and iOS) bit, includes: unix */
111 Darwin = 0b00000000000000000000100000000001U,
112 /** QNX NTO (>= 6) bit, includes: unix */
113 QnxNTO = 0b00000000000000000001000000000001U,
114 /** Generic WebAssembly bit */
115 GenWasm = 0b00000001000000000000000000000000U,
116 /** WebAssembly with Unix/Posix suport bit (emscripten) */
117 Emscripten = 0b00000001000000000000000000000001U,
118 /** Identifier for native OS type, one of the above. */
120 };
121 constexpr uint32_t number(const os_type_t rhs) noexcept {
122 return static_cast<uint32_t>(rhs);
123 }
124 constexpr os_type_t operator~(const os_type_t rhs) noexcept {
125 return static_cast<os_type_t>(~number(rhs));
126 }
127 constexpr os_type_t operator^(const os_type_t lhs, const os_type_t rhs) noexcept {
128 return static_cast<os_type_t>(number(lhs) ^ number(rhs));
129 }
130 constexpr os_type_t operator|(const os_type_t lhs, const os_type_t rhs) noexcept {
131 return static_cast<os_type_t>(number(lhs) | number(rhs));
132 }
133 constexpr os_type_t operator&(const os_type_t lhs, const os_type_t rhs) noexcept {
134 return static_cast<os_type_t>(number(lhs) & number(rhs));
135 }
136 constexpr os_type_t& operator|=(os_type_t& lhs, const os_type_t rhs) noexcept {
137 lhs = static_cast<os_type_t>(number(lhs) | number(rhs));
138 return lhs;
139 }
140 constexpr os_type_t& operator&=(os_type_t& lhs, const os_type_t rhs) noexcept {
141 lhs = static_cast<os_type_t>(number(lhs) & number(rhs));
142 return lhs;
143 }
144 constexpr os_type_t& operator^=(os_type_t& lhs, const os_type_t rhs) noexcept {
145 lhs = static_cast<os_type_t>(number(lhs) ^ number(rhs));
146 return lhs;
147 }
148 constexpr bool operator==(const os_type_t lhs, const os_type_t rhs) noexcept {
149 return number(lhs) == number(rhs);
150 }
151 constexpr bool operator!=(const os_type_t lhs, const os_type_t rhs) noexcept {
152 return !(lhs == rhs);
153 }
154 constexpr bool is_set(const os_type_t mask, const os_type_t bits) noexcept {
155 return bits == (mask & bits);
156 }
157 /**
158 * Return the string representation of os_type
159 * @param mask the os_type to convert
160 * @return the string representation.
161 */
162 std::string to_string(const os_type_t mask) noexcept;
163
164 /**
165 * Evaluates `true` if the given \ref os_type is defined,
166 * i.e. `Unix`, `Windows`, `Linux`, `Android`, ...
167 */
168 constexpr bool is_defined_os_type(const os_type_t v) noexcept {
169 switch(v) {
170 case os_type_t::Unix:
171 [[fallthrough]];
173 [[fallthrough]];
174 case os_type_t::Linux:
175 [[fallthrough]];
177 [[fallthrough]];
179 [[fallthrough]];
181 [[fallthrough]];
183 [[fallthrough]];
185 return true;
187 return true;
188 default:
189 return false;
190 }
191 }
192
193 // one static_assert is sufficient for whole compilation unit
194 static_assert( is_defined_os_type(os_type_t::native) ); // Enhance os_type to match your platform!
195
196 /** Evaluates `true` if platform os_type::native contains os_type::Unix */
197 constexpr bool is_unix() noexcept { return is_set(os_type_t::native, os_type_t::Unix); }
198
199 /** Evaluates `true` if platform os_type::native contains os_type::Windows */
200 constexpr bool is_windows() noexcept { return is_set(os_type_t::native, os_type_t::Windows); }
201
202 /** Evaluates `true` if platform os_type::native contains os_type::Linux */
203 constexpr bool is_linux() noexcept { return is_set(os_type_t::native, os_type_t::Linux); }
204
205 /** Evaluates `true` if platform os_type::native contains os_type::Android */
206 constexpr bool is_android() noexcept { return is_set(os_type_t::native, os_type_t::Android); }
207
208 /** Evaluates `true` if platform os_type::native contains os_type::FreeBSD */
209 constexpr bool is_freebsd() noexcept { return is_set(os_type_t::native, os_type_t::FreeBSD); }
210
211 /** Evaluates `true` if platform os_type::native contains os_type::Darwin */
212 constexpr bool is_darwin() noexcept { return is_set(os_type_t::native, os_type_t::Darwin); }
213
214 /** Evaluates `true` if platform os_type::native contains os_type::QnxNTO */
215 constexpr bool is_qnxnto() noexcept { return is_set(os_type_t::native, os_type_t::QnxNTO); }
216
217 /** Evaluates `true` if platform os_type::native contains os_type::GenWasm */
218 constexpr bool is_generic_wasm() noexcept { return is_set(os_type_t::native, os_type_t::GenWasm); }
219
220 /** Evaluates `true` if platform os_type::native contains os_type::Emscripten */
221 constexpr bool is_emscripten() noexcept { return is_set(os_type_t::native, os_type_t::Emscripten); }
222
224 std::string sysname;
225 std::string nodename;
226 std::string release;
227 std::string version;
228 std::string machine;
229 std::string domainname;
230 std::string to_string() noexcept {
231 std::string sb = sysname+" "+release+", "+machine;
232 if( nodename.length() > 0 ) {
233 sb.append(", node ").append(nodename);
234 }
235 if( domainname.length() > 0 ) {
236 sb.append(", domain ").append(domainname);
237 }
238 sb.append(", ").append(version);
239 return sb;
240 }
241 };
242 bool get_rt_os_info(RuntimeOSInfo& info) noexcept;
243
244 enum class abi_type_t : uint16_t {
245 generic = 0x00,
246 /** ARM GNU-EABI ARMEL -mfloat-abi=softfp */
247 gnu_armel = 0x01,
248 /** ARM GNU-EABI ARMHF -mfloat-abi=hard */
249 gnu_armhf = 0x02,
250 /** ARM EABI AARCH64 (64bit) */
251 aarch64 = 0x03,
252 /** WASM Generic (32bit) */
253 wasm32_gen = 0x20,
254 /** WASM Emscripten (32bit) */
255 wasm32_ems = 0x21,
256 /** WASM Generic (64bit) */
257 wasm64_gen = 0x2a,
258 /** WASM Emscripten (64bit) */
259 wasm64_ems = 0x2b
260 };
261 constexpr abi_type_t get_abi_type(const jau::cpu::cpu_family_t cpu) noexcept {
262 if ( jau::cpu::cpu_family_t::arm64 == cpu ) {
263 return abi_type_t::aarch64;
264 } else if ( jau::cpu::cpu_family_t::arm32 == cpu ) {
265 return abi_type_t::gnu_armhf; // FIXME?
266 } else if ( jau::cpu::cpu_family_t::wasm32 == cpu ) {
267 #if defined(__EMSCRIPTEN__)
269 #else
271 #endif
272 } else if ( jau::cpu::cpu_family_t::wasm64 == cpu ) {
273 #if defined(__EMSCRIPTEN__)
275 #else
277 #endif
278 }
279 return abi_type_t::generic;
280 }
281 inline abi_type_t get_abi_type() noexcept {
282 return get_abi_type( jau::cpu::CpuInfo::get().family );
283 }
284 std::string to_string(const abi_type_t abi) noexcept;
285
286 /**
287 * Returns the common name for the given
288 * os_type, jau::cpu::cpu_family, abi_type and endian.
289 *
290 * An excerpt of supported <code>os.and.arch</code> strings:
291 * <ul>
292 * <li>android-armv6</li>
293 * <li>android-aarch64</li>
294 * <li>android-x86</li>
295 * <li>linux-armv6</li>
296 * <li>linux-armv6hf</li>
297 * <li>linux-i586</li>
298 * <li>linux-ppc</li>
299 * <li>linux-mips</li>
300 * <li>linux-mipsel</li>
301 * <li>linux-superh</li>
302 * <li>linux-sparc</li>
303 * <li>linux-aarch64</li>
304 * <li>linux-amd64</li>
305 * <li>linux-ppc64</li>
306 * <li>linux-ppc64le</li>
307 * <li>linux-mips64</li>
308 * <li>linux-ia64</li>
309 * <li>linux-sparcv9</li>
310 * <li>linux-risc2.0</li>
311 * <li>freebsd-i586</li>
312 * <li>freebsd-amd64</li>
313 * <li>darwin-universal</li>
314 * <li>windows-amd64</li>
315 * <li>windows-i586</li>
316 * </ul>
317 * @return The <i>os.and.arch</i> value.
318 */
319 std::string get_os_and_arch(const os_type_t os, const jau::cpu::cpu_family_t cpu, const abi_type_t abi, const endian_t e) noexcept;
320
321 /** Returns this hosts's common name, see get_os_and_arch() */
322 inline std::string get_os_and_arch() noexcept {
324 }
325
326 /** Returns the OS's path separator character, e.g. `;` for Windows and `:` for Unix (rest of the world) */
327 constexpr char path_separator_char() noexcept {
328 if constexpr (jau::os::is_windows()) {
329 return ';';
330 } else {
331 return ':';
332 }
333 }
334 /** Returns the OS's path separator as a string, e.g. `;` for Windows and `:` for Unix (rest of the world) */
335 constexpr_cxx20 std::string path_separator() noexcept {
336 return std::string(1, path_separator_char());
337 }
338
339 /** Returns the OS's path separator character, e.g. `\\` for Windows and `/` for Unix (rest of the world) */
340 constexpr char dir_separator_char() noexcept {
341 if constexpr (jau::os::is_windows()) {
342 return '\\';
343 } else {
344 return '/';
345 }
346 }
347
348 /** Returns the OS's path separator as a string, e.g. `\\` for Windows and `/` for Unix (rest of the world) */
349 constexpr_cxx20 std::string dir_separator() noexcept {
350 return std::string(1, dir_separator_char());
351 }
352
353 std::string get_platform_info(std::string& sb) noexcept;
354 inline std::string get_platform_info() noexcept {
355 std::string sb; get_platform_info(sb); return sb;
356 }
357
358 /**@}*/
359
360} // namespace jau::os
361
362#endif /* JAU_OS_SUPPORT_HPP_ */
static const CpuInfo & get() noexcept
Returns reference to const singleton instance.
Definition: cpuid.hpp:356
endian_t
Endian identifier, indicating endianess of all scalar types.
Definition: byte_util.hpp:203
@ native
Identifier for native platform type, one of the above.
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
constexpr_cxx20 std::string dir_separator() noexcept
Returns the OS's path separator as a string, e.g.
Definition: os_support.hpp:349
constexpr os_type_t operator~(const os_type_t rhs) noexcept
Definition: os_support.hpp:124
constexpr os_type_t & operator&=(os_type_t &lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:140
constexpr bool operator!=(const os_type_t lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:151
constexpr bool is_defined_os_type(const os_type_t v) noexcept
Evaluates true if the given os_type is defined, i.e.
Definition: os_support.hpp:168
constexpr bool is_freebsd() noexcept
Evaluates true if platform os_type::native contains os_type::FreeBSD.
Definition: os_support.hpp:209
bool get_rt_os_info(RuntimeOSInfo &info) noexcept
Definition: os_support.cpp:69
constexpr char path_separator_char() noexcept
Returns the OS's path separator character, e.g.
Definition: os_support.hpp:327
constexpr bool is_darwin() noexcept
Evaluates true if platform os_type::native contains os_type::Darwin.
Definition: os_support.hpp:212
constexpr bool is_set(const os_type_t mask, const os_type_t bits) noexcept
Definition: os_support.hpp:154
constexpr os_type_t & operator^=(os_type_t &lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:144
constexpr bool is_emscripten() noexcept
Evaluates true if platform os_type::native contains os_type::Emscripten.
Definition: os_support.hpp:221
constexpr os_type_t operator|(const os_type_t lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:130
constexpr uint32_t number(const os_type_t rhs) noexcept
Definition: os_support.hpp:121
os_type_t
OS type bits and unique IDs.
Definition: os_support.hpp:99
constexpr bool is_unix() noexcept
Evaluates true if platform os_type::native contains os_type::Unix.
Definition: os_support.hpp:197
constexpr bool is_linux() noexcept
Evaluates true if platform os_type::native contains os_type::Linux.
Definition: os_support.hpp:203
constexpr bool operator==(const os_type_t lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:148
constexpr abi_type_t get_abi_type(const jau::cpu::cpu_family_t cpu) noexcept
Definition: os_support.hpp:261
constexpr_cxx20 std::string path_separator() noexcept
Returns the OS's path separator as a string, e.g.
Definition: os_support.hpp:335
std::string get_os_and_arch(const os_type_t os, const jau::cpu::cpu_family_t cpu, const abi_type_t abi, const endian_t e) noexcept
Returns the common name for the given os_type, jau::cpu::cpu_family, abi_type and endian.
Definition: os_support.cpp:105
constexpr bool is_qnxnto() noexcept
Evaluates true if platform os_type::native contains os_type::QnxNTO.
Definition: os_support.hpp:215
constexpr bool is_android() noexcept
Evaluates true if platform os_type::native contains os_type::Android.
Definition: os_support.hpp:206
constexpr bool is_windows() noexcept
Evaluates true if platform os_type::native contains os_type::Windows.
Definition: os_support.hpp:200
constexpr os_type_t operator&(const os_type_t lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:133
constexpr os_type_t operator^(const os_type_t lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:127
constexpr char dir_separator_char() noexcept
Returns the OS's path separator character, e.g.
Definition: os_support.hpp:340
constexpr os_type_t & operator|=(os_type_t &lhs, const os_type_t rhs) noexcept
Definition: os_support.hpp:136
std::string to_string(const os_type_t mask) noexcept
Return the string representation of os_type.
Definition: os_support.cpp:60
constexpr bool is_generic_wasm() noexcept
Evaluates true if platform os_type::native contains os_type::GenWasm.
Definition: os_support.hpp:218
std::string get_platform_info(std::string &sb) noexcept
Definition: os_support.cpp:207
@ Emscripten
WebAssembly with Unix/Posix suport bit (emscripten)
@ Unix
Unix bit, contained by: linux, android, freebsd, darwin.
@ native
Identifier for native OS type, one of the above.
@ FreeBSD
FreeBSD bit, includes: unix
@ Darwin
Darwin (Apple OSX and iOS) bit, includes: unix
@ GenWasm
Generic WebAssembly bit.
@ Windows
Windows bit.
@ QnxNTO
QNX NTO (>= 6) bit, includes: unix
@ Android
Android bit, includes: linux and unix
@ Linux
Linux bit, contained by: android; includes: unix
@ wasm32_gen
WASM Generic (32bit)
@ wasm64_gen
WASM Generic (64bit)
@ gnu_armel
ARM GNU-EABI ARMEL -mfloat-abi=softfp.
@ wasm32_ems
WASM Emscripten (32bit)
@ wasm64_ems
WASM Emscripten (64bit)
@ aarch64
ARM EABI AARCH64 (64bit)
@ gnu_armhf
ARM GNU-EABI ARMHF -mfloat-abi=hard.
cpu_family_t
Definition: cpuid.hpp:47
@ wasm64
WebAssembly 64-bit.
@ wasm32
WebAssembly 32-bit.
constexpr uint32_t get_host_os_id() noexcept
Definition: os_support.hpp:63
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2024 Gothel Software e.K.
Definition: dyn_linker.hpp:37
std::string to_string() noexcept
Definition: os_support.hpp:230