1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
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.
|