DD-WRTでのアプリケーションのクロスコンパイルに関する注意

最近、私のWi-Fiルーターが機能しなくなり、考えた後、Asus RT-N16を注文しました。 私は最終的に代替ファームウェアに精通したかった。 このルーターの特徴はすでにHabréで説明されています。 したがって、DD-WRTがインストールされ(v2.24)、sambaが巻き上げられ、システムフラッシュドライブが最初のusbポートに接続され、外部ハードドライブが2番目のusbポートに挿入されます。 そして、興味を持ちました。このルーターでプログラムを実行できますか? ネットワーク上でルーター用のプログラムを作成するためのガイドを見つけていないので、この記事でギャップを埋めたいと思っています。 これは、途中で発生する小さな問題を説明するステップバイステップガイドです。

テストプログラムとして、Easysyncを実行したいと思いました。 これは、dropboxのスタイルでファイルを同期するためのオープンプログラムであることを繰り返します。 プログラムはQt 4を使用して作成され、Unisonは同期エンジンとして使用されます。 この記事では、QIPS、Unison、Easysync for MIPSアーキテクチャのコンパイル方法について説明し、ホームルーターでEasysyncを実行する方法について説明します。

愛人のメモ。


ルーターは、平均的なユーザーには珍しいプロセッサーを使用します。 ホームユーザーは、x86アーキテクチャ、IntelおよびAMDプロセッサに慣れています。 Asus RT-N16は、 MIPSアーキテクチャを備えたBroadcom BCM4718 プロセッサを使用しています。 ルーター自体のリソースはプログラムをビルドするのに十分ではない可能性があるため、通常、プログラムはビッグブラザー(使い慣れたデスクトップコンピューターなど)でコンパイルされますが、目的のアーキテクチャ用です。 このプロセスはクロスコンパイルと呼ばれます。

道具



手順


  1. 最初に必要なことは、DD-WRTのプログラムがどのように組み立てられるかを理解することです。 Wikiのページは最新です。 特に興味深いのは、 手順セクションです。 ソースからDD-WRTを構築するために使用されるツールチェーン(以下、ツールチェーンと呼びます)へのリンクがあります。 この場合のツールチェーンは、目的のアーキテクチャ用に既にコンパイルされているUclibcライブラリとコンパイラです。 したがって、ツールチェーンはDD-WRT Webサイトからダウンロードします。 そこには書かれていませんが、すべてがx86_64アーキテクチャで構築されています。 したがって、ターミナルでuname -mと入力しても、64(x86_64またはamd64)の値が表示されない場合は、新しいバージョンのLinuxをインストールする必要があります。 別の方法は、自分でツールチェーンを構築することですが、必要なシステムをインストールすることを好みました。 ダウンロードの完了(現在は716 MB)を待ってから、次の手順に進みます。
  2. アーカイブを開きます。アーカイブには、さまざまなアーキテクチャのツールチェーンが含まれています。 toolchain-mipsel_gcc4.1.2が必要です。 このフォルダーを/ home / fralik /で解凍しました。 なぜtoolchain-mipsel_gcc4.1.2なのか? Mipsel、optwareがルーターのmipselパッケージからインストールされていることを確認したため、バイトオーダーは最低から最高(リトルエンディアン)の順に使用されます。 私の意見では、名前にmipselを含む残りのフォルダーは、DD-WRTカーネルコンポーネントの構築に使用されます。
  3. ツールチェーンをパスに追加します。
    1. PATH = $ PATH :〜 / toolchain-mipsel_gcc4.1.2 / bin /
    2. cd〜
    3. mipsel-linux-gcc --version

    GCCバージョン情報が表示されます。
  4. すべてが機能することを確認するには、2つのhelloworldプログラムを使用できます。 helloworld-cc:
    1. #include <stdlib.h>
    2. #include <stdio.h>
    3. int main {
    4. printf "Hello world! \ n " ;
    5. 0を 返し ます
    6. }

    fileコマンドを使用して収集および検証します。
    mipsel-linux-gcc helloworld-cc -o helloworld-c
    ファイル helloworld-c

    必見:
      helloworld-c:ELF 32ビットLSB実行可能ファイル、MIPS、MIPS32バージョン1(SYSV)、動的リンク(共有ライブラリを使用)、ストリップなし 


    ルータでhelloworld-cを実行し、実際に機能を確認できます。 現在helloworld-cpp.cpp:
    #define NEED_PRINTF 1
    #include <iostream>

    int main {
    std :: cout << "Hellow world!" << std :: endl ;
    0を 返し ます
    }

    ターミナル内:
    mipsel-linux-g ++ helloworld-cpp.cpp -o helloworld-cpp

    最初の行に注意してください! これがないと、プログラムはコンパイルされず、エラーが生成されます。
      /home/fralik/toolchain-mipsel_gcc4.1.2/bin/../lib/gcc/mipsel-linux-uclibc/4.1.2/../../../../include/c++/4.1.2/ cstdio:126:エラー: ':: printf'は宣言されていません 

    収集し、すべてがルーターで機能することを確認します。
  5. Qtをビルドするときです。 組み込みLinux用のQtライブラリをダウンロードします 。 ホームディレクトリでもアーカイブを解凍しました。
  6. ターミナルでQtを使用してフォルダーに移動します。 mkspecs / qwsフォルダーに注意する必要があります。 さまざまなアーキテクチャのMakeファイルを保存します。 たとえば、 mkspecs / qws / linux-mips-g ++ / qmake.confのようになります。
    linux-mips-g ++フォルダーをlinux-mipsel-g ++にコピーします。
      cp -R mkspecs / qws / linux-mips-g ++ / mkspecs / qws / linux-mipsel-g ++ 
  7. mkspecs / qws / linux-mipsesl-g ++ / qmake.confファイルを編集して、mips-linux- *ではなくmipsel-linux- *コマンドを使用するようにします。 私が使用するフラグとして
      -mel -march = mips32r2 
  8. 次に、Qtの構成に進みます。 ただし、最初にlibxext-devをインストールします。インストールしないと、エラーが発生します。
     基本的なXLib機能テストが失敗しました! 

    sudo apt-get install libxext-dev
    /構成-no-cups -release -shared -no-qt3support -no-phonon -no-audio-backend -no-javascript-jit -no-webkit -qt-sql-lite -no-script -no-scripttools -opensource -no-gui -no-nis -no-opengl -nomakeの-nomakeデモ


    必見:
      Qtはビルド用に構成されました。  「make」を実行するだけです。
    すべてがビルドされたら、「make install」を実行する必要があります。
     Qtは/usr/local/Trolltech/Qt-4.7.2にインストールされます 


    コンフィギュレーターを再度実行します。
    /構成-no-cups -release -shared -no-qt3support -no-phonon -no-audio-backend -no-javascript-jit -no-webkit -qt-sql-sqlite -no-script -no-scripttools -platform linux-g ++- 64 -xplatform qws / linux-mipsel-g ++ -opensource -no-gui -no-nis -embedded mips -little-endian -no-opengl -nomake examples -nomake demos

    初めて現在のアーキテクチャ用にQtを構成したとき、2回目はMIPS用に構成しました。 2番目のコマンドでは、 xplatform引数はステップ6で作成したフォルダーを指しているだけです。不要なもののサポートを削除しました:no-qt3support、no-phonon、no-audio-backend、-nomakeの例など。
    その結果、次のメッセージが表示されます。
      Qtはビルド用に構成されました。  「make」を実行するだけです。
    すべてがビルドされたら、「make install」を実行する必要があります。
     Qtは/usr/local/Trolltech/QtEmbedded-4.7.2-mipsにインストールされます
    
  9. makeを実行します 。 スモークまたは紅茶を飲むことができます。 =)
    このステップでは、別の問題があります。
      .obj / release-shared-emb-mips / qrect.o:関数 `QRectF :: toAlignedRect()const ':
     qrect.cpp :(。text + 0x1468): `ceilf 'への未定義の参照
     qrect.cpp :(。text + 0x1488): `ceilf 'への未定義の参照 

    事実、ceilf関数はuclibcライブラリではデフォルトで有効になっていません。 もちろん、ライブラリを再構築してそこにこの関数を追加できますが、DD-WRTツールチェーンを使用します。つまり、ルーターにはceilf関数のないライブラリもあります 。 このステップで、私は長い間タンバリンと踊り、 ceilfチャレンジをceilに変えようとしました。 しかし、Qtは揺るぎないものでした。 特にQRectクラスが必要ないことを考えると、メスを使用しなければなりませんでした。 ファイル〜/ qt-everywhere-opensource-src-4.7.2 / src / corelib / tools / qrect.cppを開き 、2379行目を見つけます。
      int xmax = int((float)((int)xp + w)); 

    つまり、呼び出しを置き換えます
      qCeil(xp + y) 
      (フロート)((int)xp + y) 
    〜/ qt-everywhere-opensource-src-4.7.2 / src / corelib / tools / qtimeline.cppファイルの行640と同様に、行2381で同様の操作を実行します
    もう一度makeを呼び出します。今回はプロセスが正常に完了するはずです。
  10. 実施します
      sudo make install 
    MIPSの下にQtライブラリがあることを確認します(インストールが/usr/local/Trolltech/QtEmbedded-4.7.2-mipsフォルダーで行われるというQtの保証にもかかわらず、すべてが/ usr / local / Trolltech / Qtにインストールされました-4.7.2 ):
    ファイル / usr / local / Trolltech / Qt-4.7.2 / lib / libQtCore.so.4.7.2

      /usr/local/Trolltech/Qt-4.7.2/lib/libQtCore.so.4.7.2:ELF 32ビットLSB共有オブジェクト、MIPS、MIPS32バージョン1(SYSV)、動的にリンク(共有ライブラリを使用)、ストリップなし 
  11. Easysyncのアセンブリに渡します。
    #いくつかのディレクトリに移動します。たとえば、
    cd〜
    git clone git: // github.com / fralik / Easysync.git
    cd easysync /サーバー
    / usr / local / Trolltech / Qt-4.7.2 / bin / qmake easysync-server.pro
    作る
    #チェック:
    ファイルビルド/ easysync-server
  12. 今、ユニゾンが必要です。 その有用性にもかかわらず、オプトウェアにはありません。 ルーターで直接収集します。 sshまたはtelnet経由でルーターにアクセスします。
    ipkg-opt install buildroot ocaml
    mkdir / mnt / unison
    cd / mnt / unison
    wget http: // www.seas.upenn.edu / 〜bcpierce / unison //ダウンロード/ release / stable / unison-2.40.61.tar.gz
    tar xvfz unison-2.40.61.tar.gz
    ocaml mkProjectInfo.ml > Makefile.ProjectInfo
    #ユニゾンを収集する前に、libncursesからlibcursesへのシンボリックリンクを作成する必要があります
    ln -s / opt / lib / libncurses.so.5.7 / opt / lib / libcurses.so.5.7
    ln -s / opt / lib / libcurses.so.5.7 / opt / lib / libcurses.so.5
    ln -s / opt / lib / libcurses.so.5 / opt / lib / libcurses.so
    NATIVE = false UISTYLE = textにします
    / unison -version
    cp /ユニゾン/オプト/ビン/ユニゾン

    ここで重要なのは、 ocaml mkProjectInfo.ml> Makefile.ProjectInfoです。 これがなければ、それは不可能です。
  13. ここで、収集したすべてを実行する必要があります。 ルーターのアドレスが192.168.2.1であり、 / mntディレクトリが書き込み用に利用可能であるとしましょう
    scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtCore.so.4.7.2 root @ 192.168.2.1:/ opt / lib
    scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtNetwork.so.4.7.2 root @ 192.168.2.1:/ opt / lib
    scp / usr / local / Trolltech / Qt-4.7.2 / lib / libQtSql.so.4.7.2 root @ 192.168.2.1:/ opt / lib /
    cd < Easysync /サーバー>
    #Easysync-serverを1つのファイルにまとめて、ルーターへの転送を容易にします。
    / build_package_dd-wrt.sh
    scp dd-wrt_bundle.tar.gz root @ 192.168.2.1:/ mnt
  14. / mntフォルダーのルーターに移動し、 easysync-server-mipsel32.tar.gzを解凍します。
    tar xvfz easysync-server_mipsel.tar.gz
    ln -s / opt / lib / libQtCore.so.4.7.2 / opt / lib / libQtCore.so.4.7
    ln -s / opt / lib / libQtCore.so.4.7 / opt / lib / libQtCore.so.4
    ln -s / opt / lib / libQtCore.so.4 / opt / lib / libQtCore.so
    ln -s / opt / lib / libQtSql.so.4.7.2 / opt / lib / libQtSql.so.4.7
    ln -s / opt / lib / libQtSql.so.4.7 / opt / lib / libQtSql.so.4
    ln -s / opt / lib / libQtSql.so.4 / opt / lib / libQtSql.so
    ln -s / opt / lib / libQtNetwork.so.4.7.2 / opt / lib / libQtNetwork.so.4.7
    ln -s / opt / lib / libQtNetwork.so.4.7 / opt / lib / libQtNetwork.so.4
    ln -s / opt / lib / libQtNetwork.so.4 / opt / lib / libQtNetwork.so
  15. さらに、Easysyncなしでユニゾンの動作を確認することは理にかなっています(ユニゾン自体のドキュメントと Easysync インストールファイルを参照できます )。 ユニゾンをセットアップした後、ルーターに戻り、 config.ini.sampleファイルを編集して実行します。
      ./setup_dd-wrt.sh 


これでホームルーターに同期サーバーができました。 外部からルーターに接続できる場合、同期はどこからでも機能します。

簡単なスクイーズ


  1. Webサイトのツールチェーンを使用して、DD-WRT用のプログラムを構築できます。 C ++プログラムの場合、 #define NEED_PRINTFを使用する必要があります。
  2. optwareアセンブリには一致しないにもかかわらず、ルーターで組み立てることができます。 原則として、クロスコンパイルを実行できますが、これは理解できませんでした。
  3. QtにはMIPSを適用してもほとんど問題はありません。プログラムのクロスプラットフォームへの+1です。
  4. Easysyncは現在、ホームルーターにも搭載されています! 再起動後、サービスが自動的に開始されないことに注意してください。 ほとんどの場合、インストール済みとしてマークされません(インストールフラグは/ tmpに格納されているため)。 / opt / bin / easysync-server -iで再度インストールするか、 / opt / etc / init.d / easysync-server startでインストールせずに実行できます。
    Easysyncに興味があるが、ソースからコンパイルしたくない人のために、既にコンパイルされたバージョンが利用可能です

    2016年5月30日更新


    Nabytovychユーザーは、一部のリンクが古くなっていることを示唆しています。 ツールチェーンとQtへのリンクを更新しました。

Source: https://habr.com/ru/post/J117194/


All Articles