Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Platform detection

A program that runs on Windows, Linux and macOS sometimes has to do things differently on each: a path separator, the name of an environment variable, a system call that exists on only one of them. The compiler predefines a symbol for the platform it is building for, and conditional compilation picks the code for it.

'' One source, three platforms: the compiler predefines a symbol for the
'' platform it builds for, and the branches for the others are never
'' compiled.
#if defined( __FB_WIN32__ )
    const PLATFORM = "Windows"
    const PATH_SEP = "\"
    const TEMP_VAR = "TEMP"
#elseif defined( __FB_LINUX__ )
    const PLATFORM = "Linux"
    const PATH_SEP = "/"
    const TEMP_VAR = "TMPDIR"
#elseif defined( __FB_DARWIN__ )
    const PLATFORM = "macOS"
    const PATH_SEP = "/"
    const TEMP_VAR = "TMPDIR"
#else
    #error "this program supports Windows, Linux and macOS only"
#endif

print "platform:      "; PLATFORM
print "a path:        logs"; PATH_SEP; "today.txt"
print "temp variable: "; TEMP_VAR

#ifdef __FB_UNIX__
    print "a Unix-like system"
#endif
#ifdef __FB_64BIT__
    print "pointers:     "; sizeof( any ptr ) * 8; " bits"
#endif
#ifdef __TIKO_COMPILER__
    print "compiled by tiko"
#endif

This is the one kind of program whose output should differ between the two targets.

Output on windows-x86_64

platform:      Windows
a path:        logs\today.txt
temp variable: TEMP
pointers:      64 bits
compiled by tiko

Output on linux-x86_64

platform:      Linux
a path:        logs/today.txt
temp variable: TMPDIR
a Unix-like system
pointers:      64 bits
compiled by tiko

Output on macos-arm64

platform:      macOS
a path:        logs/today.txt
temp variable: TMPDIR
a Unix-like system
pointers:      64 bits
compiled by tiko
SymbolDefined when building for
__FB_WIN32__Windows (the name is historical: it is defined for 64-bit Windows)
__FB_LINUX__Linux
__FB_DARWIN__macOS
__FB_UNIX__Linux, macOS, and other Unix-like systems
__FB_64BIT__every 64-bit target, which today is every target
__TIKO_COMPILER__always, by tiko

The #else branch ends in #error, so a build for any other platform stops with a clear message instead of failing later on a constant that was never declared. A branch for the platform you are not building on is never compiled there, so a typo in it goes unnoticed until someone builds for that platform: build every target you claim to support.

Test platform symbols with #ifdef or defined( ), never by value: on the other platform the name does not exist at all.

Activities

  1. Add a const for the end-of-line sequence each platform uses in text files, and print its length.
  2. Build with -target linux-x86_64 on Windows using -c, which compiles without linking, and check that the Linux branch compiles.