Here is an example of a project that builds for Linux, macOS, and Windows (extracted from https://github.com/pmunts/libsimpleio/blob/d03f21fffb81991105eeb55b6f22b3576605cd23/ada/programs/remoteio/default.gpr):
PROJECT Default IS
LIBSIMPLEIO := external("LIBSIMPLEIO", "/usr/local/share/libsimpleio");
FOR Source_Dirs USE (".",
LIBSIMPLEIO & "/ada/bindings",
LIBSIMPLEIO & "/ada/devices/**",
LIBSIMPLEIO & "/ada/interfaces",
LIBSIMPLEIO & "/ada/objects/**");
FOR Object_Dir USE "./obj";
FOR Exec_Dir USE ".";
PACKAGE Compiler IS
FOR Default_Switches ("Ada") USE
("-O3",
"-ffunction-sections",
"-fdata-sections",
"-gnata",
"-gnato1",
"-gnatVa",
"-gnatwa",
"-gnatwJ",
"-gnatwK",
"-gnat2012"
);
END Compiler;
-- Linker goop to find hidapi.dll or libhidapi.so
OS := external("OS", external("OSNAME", "unknown"));
PACKAGE Linker IS
CASE OS IS
WHEN "Windows_NT" =>
FOR Default_Switches ("ada") USE
("-L" & LIBSIMPLEIO & "/win64");
WHEN "Darwin" =>
FOR Default_Switches ("ada") USE
("-L/opt/homebrew/lib", "-ld_classic");
WHEN OTHERS =>
NULL;
END CASE;
END Linker;
END Default;
Everything is controlled by two environment variables: LIBSIMPLEIO and OS or OSNAME. LIBSIMPLEIO determines where the library packages necessary to build the program come from.
On Linux, the library packages are usually installed to /usr/local/share/libsimpleio/ada/ by a Debian or RPM package, in which case the default value for the Ada project variable is used and the eponymous environment variable is not necessary. If for some reason you don’t want to or can’t install the Debian or RPM package, you can clone https://github.com/pmunts/libsimpleio to some local directory and set LIBSIMPLEIO to point to the checkout e.g. add export LIBSIMPLEIO=$HOME/libsimpleio to .bashrc.
Since Remote I/O Protocol support for macOS and Windows was an afterthought to the Linux Simple I/O Library, there are no installation packages for macOS and Windows, so both macOS and Windows require the git checkout and LIBSIMPLEIO environment variable.
For my example, operating system idiosyncrasies manifested at link time rather than compile time and I used the OS environment variable to detect Windows and the OSNAME environment variable for all other operating systems. All of my Linux machines have OSNAME=debian13 added to /etc/environment and all of my macOS machines have export OSNAME=`uname` added to .bashrc and/or .zshrc.
Unfortunately, gprbuild provides no mechanism that I have found to do the equivalent of Unix `uname` inside the project file, which is sad because uname can provide all kinds of useful hardware target information.