co utrudnia powiedzenie, że wizualny kompilator C ++ w systemie Windows generuje binarny plik wykonywalny systemu Linux?
Poza niechęcią do zrobienia tego ze strony Microsoftu, absolutnie nic. Przeszkody nie są techniczne.
Łańcuchy narzędzi programistycznych to tylko programy, które pobierają dane wejściowe i generują dane wyjściowe. Visual C ++ tworzy asembler x86, a następnie używa asemblera do przekonwertowania go na plik obiektowy COFF. Jeśli Microsoft chciałby zamiast tego wygenerować ELF, to tylko kod: asembler wchodzi, ELF gaśnie. W plikach obiektowych lub bibliotekach nie ma nic magicznego; to tylko plamy danych w dobrze zrozumiałym formacie.
W epoce kamienia łupanego kompilacja krzyżowa była o wiele trudniejsza, ponieważ najczęściej pisanie łańcucha narzędzi dla platformy docelowej składało się na platformę, na której miałby działać. Oznaczało to, że gdyby na świecie istniały tylko architektury VAX, M68K i Alpha, pełny zestaw kompilatorów krzyżowych wymagałby napisania dziewięciu z nich, głównie od zera. (VAX-do-VAX, VAX-do-M68K, VAX-do-Alpha, M68K-do-VAX, M68K-do-M68K itp.) To trochę przesada, ponieważ części kompilatora VAX można ponownie wykorzystać i dołączone do generatorów kodu dla każdego celu (np. VAX, M68K i Alpha, każdy napisany dla VAX.)
Ten problem zniknął, gdy zaczęliśmy pisać kompilatory w języku, który nie był powiązany z konkretnym procesorem, takim jak C. Przejście tą drogą oznacza, że napisałeś cały łańcuch narzędzi raz w C i używasz platformy napisanej dla lokalnej platformy Kompilator C., aby go zbudować. (Często używasz kompilatora do ponownej kompilacji po załadowaniu go na kompilatorze platformy lokalnej, ale to kolejna dyskusja.) Wynikiem tego jest to, że zbudowanie kompilatora krzyżowego stało się zasadniczo tym samym wysiłkiem, co kompilacja natywnego kompilatora na platforma lokalna. Jedyną znaczącą różnicą jest to, że gdzieś w procesie kompilacji powiedziałeś, aby skompilował się w generatorze kodu dla platformy docelowej zamiast w przypadku platformy lokalnej, co byłoby logicznym wyborem.
W miarę ewolucji architektury kompilatorów wygodniej było po prostu włączyć i zbudować wszystkie generatory kodu wraz z produktem i wybrać, który z nich zostanie wykorzystany w czasie wykonywania. Clang / LLVM to robi i jestem pewien, że są jeszcze inni.
Gdy masz już działający zestaw narzędzi (kompilator, asembler, linker), biblioteki są budowane ze źródeł i ostatecznie kończy się wszystko, czego potrzebujesz, aby utworzyć plik wykonywalny dla innej platformy.