0

I am trying to build a lib for macOS and Linux. The reason I am writing is to know how to detect macOS 11+ and Linux in a header file.

I have the structure on cmake, and it's building, but the os.h header is not building.

How can I detect with #ifdefs whether my code is on macOS Big Sur+ vs Red Hat? I am working on both sides.

I tried to use #ifdefs without success. This lib made with cmake is a proprietary code. I read a lot here about the subject without success. Can you help me?

My os.h:

#ifndef OS_H
#define OS_H

#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>

#include <stdlib.h>
#include <map>
#include <string>
#include <sstream>
#include <vector>
#include <cstring>
#include <vector>
#include <fstream>
#include <ctype.h>

// os detection version
#ifdef Q_OS_LINUX
  std::cout << "Linux version";
#elif defined(Q_OS_CYGWIN)
  std::cout << "Cygwin version";
#else
#error "We don't support that version yet..."
#endif

#ifdef _WIN32 // Includes both 32 bit and 64 bit
        #ifdef _WIN64
            printf("Windows 64 bit\n");
        #else
            printf("Windows 32 bit\n");
        #endif
#elif __linux__
    printf("Linux\n");
#elif __unix__
    printf("Other unix OS\n");
#else
    printf("Unidentified OS\n");
#endif

#if __APPLE__
        #include "TargetConditionals.h"
        #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
            printf("iPhone stimulator\n");
        #elif TARGET_OS_IPHONE
            printf("iPhone\n");
        #elif TARGET_OS_MAC
            printf("MacOS\n");
        #else
            printf("Other Apple OS\n");
        #endif
    #else
        printf("Not an Apple OS\n");
    #endif

#if __linux__
        // linux optimized code (will fail in other platforms)
    #else
        // general code for all platforms
    #endif
    // general code

using namespace std;

#endif // OS_H

I cannot get this straight. My issue is somewhere. It's my first time with os flags. I am not used to this.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Note: there is no formal link between the compiler version and the OS your code is running on or even being compiled on. Cross-compilers confuse everything. – Botje Apr 05 '23 at 09:15
  • Take a step back and explain why you need to detect OS versions _during the compilation process_ as opposed to at runtime? – Botje Apr 05 '23 at 09:15
  • 2
    I use `#if defined(__GNUC__) && !defined(__llvm__)` to divert to rhel, and `#if defined(__APPLE__)` for mac. There are other ways, but that works for me. I use the gcc toolchain on both - although clang is switched in for the mac build. I only do this once in my entire codebase in case something messes up those switches. I then rely on my own proprietary symbols. – Bathsheba Apr 05 '23 at 09:18
  • I am trying to detect os version over runtime. I know it's hard and confusing. I am trying to do this because I want to port for RED HAT under a cmake. Trying to avoid two compilations. Maybe, I will detect it to run on docker or podman. Perhaps I will do both versions. If things are not straight I will compile for both. – Pedro Vicente Apr 05 '23 at 09:19
  • 2
    What does "trying to avoid two compilations" mean? MacOS and Linux have fundamentally different executable formats. – Botje Apr 05 '23 at 09:29
  • Never mind. I wanted to say two compilations with the same code. Thanks – Pedro Vicente Apr 05 '23 at 09:37
  • I want to build same code with different architectures – Pedro Vicente Apr 05 '23 at 09:37
  • 1
    You need to compile separately for Mac and for Linux. A Mac binary cannot run on Linux and vice versa. – Jabberwocky Apr 05 '23 at 09:42
  • But can I detect it on my header os.h? With the flags are showing here? – Pedro Vicente Apr 05 '23 at 09:45
  • What's wrong with `#if defined(__APPLE__) //you're compiling for Mac #else you're not compiling for Mac #endif`. Also you write _"I tried to use ifdefs without success."_: [edit] and show what you've tried. – Jabberwocky Apr 05 '23 at 09:49
  • I had a #error instruction and didn't work. For instance, if I build on my both machines with cmake, they work. But this #error is giving me a warning. I can't bypass them. – Pedro Vicente Apr 05 '23 at 09:51
  • 1
    @PedroVicente please [edit] and share all details in the question. – Jabberwocky Apr 05 '23 at 10:08
  • Clearly `Q_OS_LINUX` and `Q_OS_CYGWIN` are not defined when compiling for MacOS, which is why you hit the `#error`. You need another `#elif` branch to handle MacOS before reaching the `#error`. Or, just get rid of that whole `#ifdef`/`#elif` block completely, since you are using other `#if`s later in the file to handle the various platforms (including an `#elif` for `TARGET_OS_MAC`) – Remy Lebeau Apr 05 '23 at 17:45

0 Answers0