Dlaczego kompilatory zazwyczaj generują pliki wykonywalne tylko dla platformy, na której są zainstalowane?

10

Jestem programistą C ++ i starając się lepiej zrozumieć rozwój międzyplatformowy, staram się lepiej zrozumieć niektóre szczegóły implementacyjne kompilatorów i jak dokładnie tworzą one pliki binarne specyficzne dla systemu operacyjnego. W trakcie moich badań zdałem sobie sprawę, że przynajmniej przez jakiś czas większość kompilatorów pobranych na określoną platformę kompilowała tylko pliki binarne dla tej platformy. Więc jeśli pobrałeś IDE, które było dostarczane z exe kompilatora dla Windows, to ten kompilator byłby w stanie skompilować twój program tylko dla aplikacji Windows x86-x64, a nie dla aplikacji Linux lub Mac.

Teraz rozumiem, że różne platformy wymagają różnych formatów binarnych, ale co sprawia, że ​​trudno jest powiedzieć, że kompilator Visual C ++ w systemie Windows generuje binarny plik wykonywalny z Linuksem? Dopóki masz instrukcje montażu dla procesora, na którym pracujesz, a także bibliotek specyficznych dla systemu operacyjnego, czy nie powinieneś być w stanie skompilować ekwipunku dla dowolnej platformy na jakiejkolwiek maszynie?

Jason
źródło
5
Istnieje wiele kompilatorów krzyżowych: nie jestem pewien, dlaczego uważasz, że kompilacja krzyżowa jest rzadka. Visual C ++ ma sens, biorąc pod uwagę, że Microsoft chce zablokować system Windows, ale nawet udostępnia narzędzia kompilatora Androida w VS2017.
Wydaje się, że wiele innych stron wydaje się, że kompilator wielu kompilacji jest bardzo trudny do wdrożenia i dopiero do niedawna pojawiło się więcej kompilatorów międzyplatformowych. Jeśli to prawda, to zastanawiam się, co mogłoby utrudnić kompilację skrośną, jeśli potrzebujesz tylko pewnych instrukcji montażu procesora i rodzimych wywołań systemowych dla odpowiedniego systemu operacyjnego
Jason
Myślę, że masz tutaj problem ze zrozumieniem terminologii, który może być mylący. Używasz zamiennie „kompilatora wieloplatformowego” i „kompilatora wieloplatformowego”, ale są to różne rzeczy (choć powiązane): kompilator krzyżowy to kompilator dla platformy innej niż ta, której używasz, i takie rzeczy są dostępne od tak dawna, jak to są kompilatory. Kompilator wieloplatformowy to kompilator, który wykorzystuje etap pośredni do oddzielenia przetwarzania i optymalizacji języka źródłowego od generowania kodu specyficznego dla platformy, aby można go było używać. ..
Jules
... do kompilowania kodu dla wielu platform docelowych z minimalnymi zmianami. Takie rzeczy są nowszą i znacznie bardziej złożoną innowacją.
Jules

Odpowiedzi:

18

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.

Blrfl
źródło
To jest teraz najlepsza, najbardziej dogłębna odpowiedź. Myślę, że historia naprawdę pomaga zrozumieć kontekst.
Jason
3
@Jason Czasem opłaca się być starym. :-)
Blrfl
4
„Poza niechęcią do zrobienia tego ze strony Microsoftu, absolutnie nic”. - Nie nazwałbym tego „niechęcią”. Microsoft jest spółką publiczną zorientowaną na zysk; mają pewne obowiązki wobec swoich akcjonariuszy i interesariuszy. Musieliby zatrudniać, szkolić i płacić programistom dla backendu Linuksa, musieliby zatrudniać, szkolić i płacić testerów dla backendu Linuksa, musieliby zatrudniać, szkolić i płacić pracownikom wsparcia znającym backend Linuxa, musieliby zaprojektować, opracować, utrzymywać, obsługiwać i rozszerzać kod, wszystko na platformę, która jest…
Jörg W Mittag
… Poza podstawową działalnością. A wszystko po to, aby dodać n + 1 kompilator do już istniejących n kompilatorów, których równie dobrze można użyć. Jakie korzyści biznesowe dla Microsoft miałaby konkurować z GCC, Clang, ICC (Intel), xlc (IBM), Digital Mars, tcc, pcc, TenDRA, Metrowerks, PathScale,…? Osobiście nie wydaje mi się, żeby takie było.
Jörg W Mittag
3
@ JörgWMittag What would be the business benefit ... I don't think there is any.- To dobry powód, by nie chcieć tego robić.
Blrfl
8

Tak, jeśli masz wszystkie informacje o platformie docelowej, nie powinno mieć znaczenia, na jakiej platformie faktycznie pracujesz.

Istnieją dwa problemy, które zwykle się pojawiają:

  1. Ludzie nie skupiają się na tym, ponieważ jest to mniej powszechny scenariusz. Często jedyną rzeczą, którą krzyżujesz, jest kompilator, dzięki czemu możesz zatrzymać kompilację krzyżową. Mniej skupienia oznacza gorsze wsparcie.
  2. Nietrywialne programy wymagają czegoś więcej niż tylko kodu. Radzenie sobie z włączaniem / łączeniem bibliotek staje się nieco łatwiejsze, gdy masz biblioteki dla platformy, na której pracujesz. Będą w znanym miejscu, w znanym kodowaniu.

To oczywiście nie do pokonania. Przeważnie dostajesz kompilatory ukierunkowane na platformę, na której działają, ponieważ tego właśnie chcą ludzie.

Telastyn
źródło
Widzę. Dziękuję za wyjaśnienie. Zdecydowanie ma teraz dla mnie więcej sensu.
Jason
Obwiniam to za inteligencję.
JeffO
2

Nie zgadzam się z twoim założeniem. Istnieją miliony programistów Androida i iOS. I wszystkie kompilatory użytku w systemie Windows lub Mac, pisanie kodu dla zupełnie innego komputera.

Nie dostaniesz kompilatora krzyżowego, jeśli nie będzie na niego zapotrzebowania rynku. Na przykład osoby opracowujące kod dla pulpitu systemu Linux w większości mają dostęp do pulpitu systemu Linux i będą korzystać z kompilatora opartego na systemie Linux - znacznie szybciej, jeśli można uruchomić aplikację bezpośrednio na komputerze, na którym jest ona skompilowana, bez przesyłania jej przez sieć, znacznie łatwiej i szybciej mieć debugger działający na tym samym komputerze i tak dalej.

Więc o ile więcej pieniędzy zarobiłby Microsoft, gdyby ich kompilatory również budowały dla Linuxa? Około 0 USD. O ile więcej programów zostanie utworzonych dla systemu Windows? Żaden. O ile więcej oprogramowania Linux zostałoby utworzone? Nie mam pojęcia, ale Microsoft nie dba o to. Jaki byłby koszt? Całkiem znacząco. Kompilatory muszą być wolne od błędów. Muszą zostać przetestowane.

Kolejny problem: jeśli piszesz kompilator w systemie Windows, potrzebujesz kogoś, kto wie, jak pisać oprogramowanie Windows. Jeśli piszesz kompilator dla systemu Linux, potrzebujesz kogoś, kto wie, jak pisać oprogramowanie dla systemu Linux. Jeśli napiszesz kompilator dla systemu Linux działający w systemie Windows, nagle potrzebujesz znacznie rzadszego chleba programisty, który zna zarówno system Windows, jak i Linux.

gnasher729
źródło
„Istnieją miliony programistów Androida i iOS. Wszyscy używają kompilatorów działających w systemie Windows lub Mac, tworząc kod dla zupełnie innego komputera”. Nie, nie oni nie. Wielu analityków Androida korzysta z Linuksa, a według ankiety StackExchange jest to najpopularniejsza platforma dla programistów.
Miles Rout