Detecting the OS/CPU/libc/rtld of the target ============================================ This is necessary to set the "default target" in the compiler, so programs get compiled for the host platform by default. Solution 1: Build a "hello world" program and analyze it -------------------------------------------------------- 1. Build the stage1 compiler as usual, using $(HOSTCC) 2. Compile a "hello world" program with $(CC) $(CFLAGS), instead of the $(HOSTCC) that the stage1 and stage2 compilers are built with. 3. Build a program with $(HOSTCC) to analyze the "hello world" program. The following information is needed: - Executable format (ELF, PE, Mach-O, a.out, etc.) - Format bitness (32 or 64 bit format, can be smaller than bitness of CPU architecture) - CPU architecture - OS / Calling convention - If applicable: libc.so file - If applicable: ELF program interpreter / RTLD 4. Write this information to a "DefaultTargetConfig.slul" file in the compiler source directory. - The stage1 compiler could just special case this class, and provide a dummy builtin. 5. Build the stage2 compiler (and maybe rebuilt it to produce stage3 etc.) In order to support self-hosting also, there could be a command-line flag to the SLUL compiler to simulate precense of the DefaultTargetConfig.slul file if absent, with essentially copied contents from what the source/old compiler saw. That way, the destination/new compiler would get the same target as the old one. Solution 2: Analyze some existing program ----------------------------------------- Like solution 1, but try to find some existing program. However, different systems have different commands (e.g. there's no /bin/cat on Windows), and it also won't work with cross-compilations. Solution 3: Never auto-detect. Require explicitly setting the target -------------------------------------------------------------------- The target could be set via a make variable that sets a C #define. Solution 4: Detect at runtime ----------------------------- Could check different sources. First, check for cross-compilation: 1. Command-line option --target=xxxx 2. TARGET environment variable. 3. CC environment variable. If set, try to detect the what kind of compiler it is and (gcc, clang, tcc, MSVC, etc.). (BUT: I don't think this really is any environment variable? Isn't it just a Makefile variable?) Second, "copy" the target from the compiler executable: 4. Finding the compilers own executable image: - Reading auxval to find self (if somehow exposed by RTL) - Calling GetModuleHandle on Windows, and reading the PEB (don't remember exactly how this worked). 5. /proc/self, if available/mounted/allowed Lastly, try to identify from the system: 6. Checking the environment variables might give a clue: - PATH starting with / => *nix - PATH starting with ?:\ => Windows - BUT... PATH can start with `.` or something else in both cases. On Windows, PATH will contain `:` if it contains at least two entries. - WINVER on Windows? - SHELL on *nix - $_ on *nix (but on Dash, this is the name previous command, while under Bash is is the full/real path!) 6. Try to read from different paths, e.g. /bin/cat, $SHELL, $_, etc.