C++ の世界におけるクロスコンパイルの状況について

Linux から単純な Windows および OSX アプリケーションをコンパイルする一連の記事を書きました。

楽しんでいただけたでしょうか。私にとって、それは確かにかなりの旅でした。または1つの始まり。改善の余地はたくさんあり、Android や iOS などの他のいくつかの主要なオペレーティング システムを含め、未開拓の領域を残しました。デバッグについても話しませんでした。

オープンソース コミュニティは素晴らしいです。 llvm、wine、darling、さらには osxcross などのプロジェクトを当然のことと考えるべきではありません。

そして、それは実際に機能します。 Windows と Mac 用のアプリケーションをビルドして実行することさえできました。それは素晴らしいことです。

もちろん、私は何も発明しませんでした。 Boris Kolpackov は、2015 年に Linux 上で動作する cl.exe のデモを行いました。 Linux の人々は黎明期から他のアーキテクチャ用にクロス コンパイルを行っており、mingw64 は非常に人気があります。

ただし、問題があります。ほとんどの問題は、ターゲット OS ベンダーがクロス コンパイルを困難にしていることに要約できます。コンパイラの人ではありませんが、彼らは素晴らしいです。パッケージャー。 Windows、OSX、さらには Qt で発生したすべての問題は、法的な考慮事項とパッケージングの問題で解決されました。仮定は黒魔術に変わりました。クロス プラットフォームであることが判明したため、Black Magic はそうではありません。

ファイルシステムのレイアウト、ツール、またはホスト アーキテクチャを想定しないでください。

OSX および Windows SDK とツールチェーンをインストールするためのより適切で合法的な方法があれば、クロス コンパイルの改善により多くの人が投資されると思います。それほど時間はかかりません。

なぜわざわざ?

エイリアンのツールチェーンは、友達を困惑させる目新しさのように思えるかもしれませんが、信じられないほど便利です。

自動化

Windows と OSX で継続的インテグレーションを行うことは簡単ではありません。 Linux には、コンテナー化のサポート、優れた仮想化の話、膨大な範囲の管理および監視ツールがあります。そのため、選択できる場合は、CI サーバーとエージェントを Linux で実行することをお勧めします。 Windows と Mac へのクロス コンパイル機能により、システム管理がはるかに簡単になります。また、必要なハードウェアが少なくなり、各ノードのコストとアイドル時間が削減されます。

ビルドを中断しない

マージされる前にすべてのコミットをチェックするゲートキーパーが必要ですが、より多くのプラットフォームでコードをテストした場合は、コードがすべてのプラットフォームでコンパイルされることが保証されます.

迅速な開発

クロスプラットフォーム アプリケーションを作成する場合、遅かれ早かれ、プラットフォーム固有の API を使用しなければならなくなる可能性があります。機能を実装するためにプラットフォームを切り替えるには、信じられないほどの時間がかかります。単一の開発環境にとどまるほど、生産性が向上します。

移植性と信頼性

ワークフロー内のコンパイラとツールチェーンが多いほど、コードはより堅牢になり、移植性も高くなります。コンパイラが異なれば、警告セットも動作も異なります。その人生の事実をあなたの没落に任せるか、それを資産として使用することができます!

テスト

ワインとダーリンは素晴らしいものですが、もちろん品質保証テストには適していません.

ソフトウェアが Windows 7 から 10 で実行される場合は、これらすべてのプラットフォームでテストする必要があります。

ただし、アプリケーションの Linux バージョンを出荷していない場合は (出荷する必要があります)、時々 wine で実行できます。

しかし、ほとんどの単体テストは wine / darling で動作するはずです。それを有利に利用してください

ビルド システムに関する余談

このシリーズでは、QBS を使用しました。変な選択です。事実上誰も使っていないものについて書くのはなぜですか?なぜ CMake ではないのですか?

まず、QBS は言語に依存しません。 C++ および C++ ツールチェーンに関連するものはすべて、JavaScript ファイルでスクリプト化されています。かなりハッキング可能です。

そのため、他のビルド システムよりも積極的にツールチェーンを横断することができます。また、同じ呼び出し中に、さまざまなターゲット システムの複数のターゲットを並行して構築することもできます。その機能を備えたビルドシステムはほとんどありません。 build2 はおそらく唯一の他のオプションです。また、build2 は、すべての点で、驚くべきビルド システムであり、いくつかの点で QBS よりも優れています (たとえば、C++ モジュールをサポートしています)。

ただし、Qt はサポートされていません。これは理論的には修正される可能性がありますが、qbs には依然として大きな利点があります。

build2 と QBS の両方が、ビルド グラフを完全に制御できるため、かなりワイルドなことを実行できます。異なるアーキテクチャ用に、複数の独立したターゲットを並行して構築するのと同様です。

実際、認識しているすべてのプロファイルを同時に構築できます。ここで、すべてのコンパイラ用に hello world を構築します

それを目指している別のものとしてのQBS。正気で理解された構文:QML.そして、現在利用可能なビルド ツールの中で最高の言語を提供していると心から信じています。

QML は約 10 年前のもので、明確で確立されたルールです。もちろん、JavaScript の使用を嫌うのは流行っていますが、スクリプトは強力ですが、ビルド ファイルの保守が困難になるほど強力ではありません。すべての意図と目的のために、構文は直感的なロジックを持つ宣言型です。その点で、scons、waf などの問題を回避できます。

簡潔さよりも使いやすさに重点を置いています。

そして最も重要なことは、ビルド システム ジェネレーターではなく、ビルド システムであることです。ファイルやフラグなどの変更を適切に検出し、それに応じてグラフを再構築します。

もちろん、build2 にも他の機能と同様にその機能があります。

ただし、CMake にはこれらのプロパティがありません。

どこにでもあるというだけでは、CMake を引き換えるのに十分な品質ではないと思います。CMake は、最終的には、ひどい構文と劣悪なドキュメントを備えた別の Makefile ジェネレーターにすぎません。

今後のプロジェクトでは、 qbs または build2 の使用を検討してください。あなたがライブラリ ライターである場合は、ユーザーがライブラリにリンクできるように cmake ファイルを提供できます。世界が優れたビルド システムに落ち着いたら、優れた C++ パッケージ マネージャーを提供することははるかに簡単になります。

QBS はいくつかの Qt 共有ライブラリにリンクしています。もちろん、それはマイナス面です。書き直されることを願っています。できれば手を貸してください。しかし、次のプロジェクトを開始するときに QBS を検討することを止めるものではありません。

クロス コンパイル ストーリーを改善するために何ができるでしょうか?

Microsoft と Apple に、システム SDK を入手するためのより簡単な方法を提供するよう依頼してください

Microsoft と Apple の両方が SDK を tarball として出荷し、再配布方法に制限がなければ、オープン ソース コミュニティがそれらを使用してアプリを構築することがはるかに簡単になります。ウィンウィンです。 XCode と Windows SDK はどちらもライセンス コストがかからず、合法的ではありませんが、既にそれらを共有することが可能であるため、win-win の関係になるはずです。

ビルド ツールにホストとターゲット システムに関する仮定を組み込まないでください

理想的には、ビルド ツールが提供するすべての機能が、ターゲットの追加が容易なクロス プラットフォームであるべきです。ただし、Qt ビルド スクリプトで見られるように、多くの場合、そうではありません。QBS は Linux で .plist を処理できません。

私が触れなかったもう 1 つの問題は、コード署名です。 Linux から Windows アプリケーションに署名することは可能ですが、OSX アプリケーションについては同じことが言えません。一部のオープンソース プロジェクトはそれを解決します。

ワインとダーリンをサポート

Wine と Darling はどちらも素晴らしいオープン ソース プロジェクトです。しかし、彼らの仕事は膨大です。確かに、wine はゲームに最適ですが、すばらしい開発ツールと見なされるべきです。

Linux で iOS シミュレーターを実行することを想像してみてください。

そのためには、おそらく資金、会社の支援、開発者の時間が必要です。

LLVM に感謝

ここで紹介した内容のほとんどは、LLVM なしでは実現できませんでした。幸いなことに、これは十分な資金が提供されたプロジェクトですが、彼らが何らかの助けを借りることができると確信しています. lld に .tbd ファイルのサポートを追加することは、すばらしいプロジェクトです。 tdb ファイルのアイデアが気に入っています。すべてのプラットフォームで使用できるようにする必要がありますか?

ユニバーサル ツールチェーン記述子?

私は賢くて独創的だと思っていましたが、どうやらそのアイデアは Cpp Slack で既に議論されていたようです.

ツールチェーンは、このシリーズで説明したように、比較的単純でよく理解されているものです。それは、コンパイラ、リンカ、アセンブリをコンパイルするためのその他のツール、シンボルの削除です。インクルード パスとライブラリ パスの束であり、まれにフラグの束です。

では、エイリアンのツールチェーンを含む任意の C++ ツールチェーンを記述するファイルを作成したらどうなるでしょうか。これは QBS プロファイルと非常に似ていますが、YAML などの同じ構文を使用します。

さまざまなシステムでそのファイルの標準的な場所を指定できます。また、ビルド システムはそれを読み取ってツールチェーンを検出できます (黒魔術に頼る代わりに、またはそれに加えて)。

もちろん、すべてのビルド システムがそのファイルを使用する意思がある場合にのみ、実際に機能します。

それは追求する価値があると思いますか?