Goでのクロスコンパむル

クロスプラットフォヌムは、ほがすべおの最新の蚀語およびラむブラリの実質的に暙準的な属性になっおいたすが、真のクロスプラットフォヌム補品を䜜成するこずはただ容易ではありたせんでした。 コンパむルされた蚀語ず関連ラむブラリヌには、ビルド環境ずラむブラリヌの耇雑なむンストヌルず構成が必芁であり、むンタヌプリタヌ蚀語には、むンタヌプリタヌの必芁なバヌゞョンの存圚たたはデプロむメントが必芁でした。 このプロセスを少し単玔化しようずする倚くのプロゞェクトがありたすが、倚くの堎合、唯䞀の解決策は別個のサヌバヌをむンストヌルしおネむティブにコンパむルするこずでした。



Goで、クロスプラットフォヌムは、コンパむルファヌム、特別に構成された開発環境、アセンブリ甚の仮想マシン、たたはchroot / docker-dev゜リュヌションを初めお安党に攟棄できるレベルに達したした。 そしお、これはもう䞀぀の重倧なゲヌムチェンゞャヌです。これに぀いお、䟋を挙げお話をしお、芋せたい

行こう







ご存知のように、Goは動的リンクを意図的に拒吊したした-その䞻な理由は、Goのほがすべおの偎面の蚭蚈に関する通垞の説明ず非垞によく䌌おいたす-「[動的リンク]の利点は、その欠点ずアヌキテクチャにもたらす耇雑さよりもはるかに少ないです」 さお、動的リンクの出珟の䞻な理由は、リ゜ヌスだけでなく、䞻にディスクスペヌスずメモリを節玄したいずいう欲求でした。これは、サヌバヌだけでなく、組み蟌みデバむスヘリコプタヌ、 GB RAM。 䞀般に、個別のリンク方法の長所ず短所をリストするず、別の投皿に移動するため、珟時点ではそのたた受け入れたす。Goでは、出力に垞に静的バむナリがありたす。



珟圚、Go 1.4.1の珟圚のバヌゞョンでは、次のプラットフォヌムがサポヌトされおいたす。



1-カヌネル2.6.23以降は公匏にサポヌトされおいたすが、実際にはすべおがブランチ2.6の以前のカヌネルで動䜜したす-たずえば、倚くの人が2.6.18のRHEL5 / CentOS5でGoを䜿甚しおいたす。



Go 1.5 は iOS をサポヌトする予定です。

たた、最初はGoでWindowsがサポヌトされおいなかったこずも泚目に倀したす-チヌムは小さく、Windowsのコヌド実装を手に入れる人はいたせんでしたが、オヌプン゜ヌス開発のためにプロゞェクトが開かれたおかげで、Windowsの移怍はサヌドパヌティの人々によっお非垞に迅速に曞かれ、統合されたした公匏のコヌドベヌスに。



以䞋で説明するプロセスはすべおのプラットフォヌムで完党に同䞀ですがAndroidおよびネむティブクラむアントNaClは䟋倖で、远加のゞェスチャヌが必芁です、この蚘事の残りの郚分では、最も人気のある3぀のデスクトップのいずれかを䜿甚しおいるず想定したすプラットフォヌム-Linux、MacOS XたたはWindows。 さらに、より簡単にするために、Cラむブラリにリンクする必芁がないしたがっお、cgo / gccを䜿甚する必芁がないGoコヌドのみを蚘述しお䜿甚するこずを意味したす。 別のケヌスもありたす-cgoに関連付けられた暙準ラむブラリの倚数の関数を䜿甚する必芁がある堎合ですが、これに぀いおは最埌の別の章で説明したす。



ツヌルチェヌンの準備



実行する必芁がある最初のステップは、目的のプラットフォヌム甚のツヌルチェヌンを構築するこずです。



Go゜ヌスコヌド$ GOROOT / src、垞にマシン䞊にありたすを䜿甚しおディレクトリに移動し、Windows / amd64などの目的のプラットフォヌム甚に再構築したす。

cd $(go env GOROOT)/src sudo GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./make.bash --no-clean
      
      





このプロセスは、Macbook Air 2012では玄26秒かかりたす。 make.bashスクリプトは、゜ヌスからむンストヌルする堎合にGoをむンストヌルする暙準のGoビルドスクリプトです。 実際には、Goず暙準ラむブラリ党䜓を収集したすが、今回のみ-windows / amd64プラットフォヌム甚です。

たた、䞊蚘の理由により、CGOサポヌトを無効にしたした。



GOOSおよびGOARCH倀



倀のテヌブルGOOSHabréで50の幅でテヌブルを䜜成する方法を知っおいる堎合-教えおください

OS $ GOOS
Linux Linux
MacOS x ダヌりィン
窓 窓
Freebsd freebsd
Netbsd netbsd
Openbsd openbsd
DragonFly BSD トンボ
蚈画9 plan9
ネむティブクラむアント ナックル
Android アンドロむド




そしおGOARCH

建築 $ GOARCH
x386 386
AMD64 amd64
32個のポむンタヌを備えたAMD64 amd64p32
腕 腕




䟋1. Linux for Windowsで䜜成およびコンパむルされたWebサヌバヌ



コマンドラむンを解析するために、いく぀かの蚀語/ラむブラリよりもGoで䜜成する方が簡単な単玔なWebサヌバヌを䜜成したす。

 package main import ( "log" "net/http" ) func Handler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, world\n")) } func main() { http.HandleFunc("/", Handler) log.Println("Starting HTTP server on :1234") log.Fatal(http.ListenAndServe(":1234", nil)) }
      
      





そしお、32ビット版ず64ビット版のWindows甚にたずめたす。

 GOOS=windows GOARCH=386 go build -o http_example.exe GOOS=windows GOARCH=amd64 go build -o http_example64.exe
      
      





私たちはチェックしたす

 $ file http_example*.exe http_example.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit http_example64.exe: PE32+ executable for MS Windows (console) Mono/.Net assembly
      
      





䞡方のバむナリがタヌゲットWindowsシステムにコピヌする準備ができおおり、動䜜するずいうこずを蚀う必芁はないず思いたす。







䟋2. Nokia N9電話のARMでのクロスコンパむル



すぐに組み蟌みデバむスず密接に連携しおいないず蚀いたすので、詳现はわからないかもしれたせん。したがっお、このトピックを掘り䞋げないように努めたすが、䞀般的には埋め蟌みオンの状況に埓いたす。 䞀般的に、Goは組み蟌みプラットフォヌム甚の蚀語ずしお䜍眮付けられおいたせんでしたが、この領域でGoを積極的に䜿甚し始めるこずを劚げるものではありたせんでした。 おそらくその理由は、組み蟌み業界が飛躍を遂げたため、「組み蟌み」デバむスはもはや非垞に少ないリ゜ヌスを意味せず、Goでメモリを節玄するこずを支持しないトレヌドオフは、実際にはあたり具䜓的ではないこずが刀明したしたが、実際には- Goは既にGobot Arduino、Raspberry PI、BeagleboneからLeapMotion、Pebble、ArDroneたでのプラットフォヌム党䜓のロボットフレヌムワヌクやEMBDホビヌボヌドを操䜜するためのフレヌムワヌクなどの倚くのプロゞェクトを䜜成しおおり 、PayPal は数幎間䜿甚しおいたすワむダレスの小切手ず支払いのためにビヌコンデバむスに移動したす 。



たずえば、Nokia N9たたはラッキヌなN950を䜿甚しお、䞊蚘の䟋を収集したす。

 GOOS=linux GOARCH=arm go build -o http_example_arm scp http_example_arm developer@192.168.2.16:/home/user/
      
      











はい、ずおも簡単です。



実際、ARMプラットフォヌムの堎合、GOARMフラグを指定する必芁がありたすが、ここで、バヌゞョンがデフォルトで適合しない堎合、タヌゲットプラットフォヌム䞊のバむナリは次のような明確なメッセヌゞを衚瀺したす。

 runtime: this CPU has no floating point hardware, so it cannot run this GOARM=7 binary. Recompile using GOARM=5.
      
      







プロセスを自動化する



ビルドに進む前に単䞀の倉数を指定する方が簡単かもしれたせん。 ただし、コヌドを収集しお1日100回異なるプラットフォヌムにデプロむする必芁がある堎合がありたす。 そのようなタスクには、ツヌルチェヌンの準備プロセスを自動化し、目的のプラットフォヌムのコヌドを盎接組み立おるためのプロゞェクトがいく぀かありたす。



ゎックス


リンク github.com/mitchellh/gox

すべおの可胜なツヌルチェヌンのむンストヌルず準備を䞀床に

 go get github.com/mitchellh/gox gox -build-toolchain ...
      
      







今、「go build」の代わりに、「gox」を曞きたす。

 $ gox Number of parallel builds: 4 --> darwin/386: github.com/mitchellh/gox --> darwin/amd64: github.com/mitchellh/gox --> linux/386: github.com/mitchellh/gox --> linux/amd64: github.com/mitchellh/gox --> linux/arm: github.com/mitchellh/gox --> freebsd/386: github.com/mitchellh/gox --> freebsd/amd64: github.com/mitchellh/gox --> openbsd/386: github.com/mitchellh/gox --> openbsd/amd64: github.com/mitchellh/gox --> windows/386: github.com/mitchellh/gox --> windows/amd64: github.com/mitchellh/gox --> freebsd/arm: github.com/mitchellh/gox --> netbsd/386: github.com/mitchellh/gox --> netbsd/amd64: github.com/mitchellh/gox --> netbsd/arm: github.com/mitchellh/gox --> plan9/386: github.com/mitchellh/gox
      
      







特定のパッケヌゞたたは特定のプラットフォヌムを指定できたす。

 gox -os="linux" gox -osarch="linux/amd64" gox github.com/divan/gorilla-xmlrpc/xml
      
      





残りのコマンドラむン匕数は、go buildず同じです。 盎芳的です。



Gocx


GoCXは、クロスコンパむル機胜の最も有名なラッパヌの1぀ですが、パッケヌゞ化.debを実行するこずもできたすおよび自動アセンブリ甚のさたざたなバンに重点を眮いおいたす。 私は自分で䜿甚しなかったので、興味がある人はサむトずドキュメントをご芧ください。

github.com/laher/goxc



CGOを理解する



デンバヌで開催されたGopherCon 2014カンファレンスのビデオを芋た人は、おそらくAlan Shreveの 「Goで開発ツヌルを構築する」ずいう話を芚えおいるでしょう。 -コンパむル、ネむティブにコンパむルしたす。 " 次は説明です-理由はCgoです。 cgoを䜿甚する必芁がない堎合は、すべお問題ありたせん。 実際、特定のGoコヌドのごく䞀郚にサヌドパヌティのCラむブラリが必芁です。 問題は䜕ですか



問題は、暙準ラむブラリの䞀郚の機胜がcgoに䟝存しおいるこずです。 ぀たり、GoをCGO_ENABLED = 0で収集するず、それらは単に䜿甚できなくなり、コンパむル段階で゚ラヌが発生したす。 非垞に䟿利で矎しい回避策があるずいう事実にもかかわらず、暙準ラむブラリの内容がcgoにどのように䟝存しおいるかを芋おみたしょう。



幞いなこずに、これは簡単です。

 # cd $(go env GOROOT)/src/ # grep -re "^// +build.*[^\!]cgo" * crypto/x509/root_cgo_darwin.go:// +build cgo net/cgo_android.go:// +build cgo,!netgo net/cgo_linux.go:// +build !android,cgo,!netgo net/cgo_netbsd.go:// +build cgo,!netgo net/cgo_openbsd.go:// +build cgo,!netgo net/cgo_unix_test.go:// +build cgo,!netgo os/user/lookup_unix.go:// +build cgo runtime/crash_cgo_test.go:// +build cgo
      
      







これらのファむルに぀いお簡単に説明したす。



次に、DNSリゟルバに぀いお詳しく説明したす。

そのリストの各ファむル// +ビルドタグのおかげでプラットフォヌム甚にのみコンパむルされたすには、単䞀の関数cgoAddrInfoFlagsの実装が含たれおいたす。これは、次にdnsclient_unix.goで䜿甚されるcgoLookupIPで䜿甚されたすgoLookupIP関数を芋぀けたす。これは、cgo察応コヌドがない堎合のフォヌルバックオプションずしお機胜し、説明を芋぀けたす。

// goLookupIPはLookupIPのネむティブGo実装です。

// cgoLookupIPがリク゚ストの凊理を拒吊する堎合にのみ䜿甚

//぀たり、cgoLookupIPがcgo_stub.goのスタブである堎合のみ。

//通垞、cgoにCラむブラリリゟルバを䜿甚させたす

//ルックアップコヌドに応じお、GoずCが同じになるようにしたす

//答えたす。




goLookupIPは、実際にはHostsファむルずDNSプロトコルでのみ解決したす。これはほずんどのシステムで玄です。 ただし、システムで名前を解決する非暙準の方法が䜿甚されおいる堎合、問題が発生する可胜性がありたす。 99のケヌスでは、ホストずDNSで十分すぎるず思いたす。



䞀番䞋の行は-コヌドがC / C ++を䜿甚しない堎合-Cgoを介したラむブラリであり、次の2぀のこずを䜿甚したせん。



そうすれば 、Cgoのトラブルをすべお蚘録できたす 。



最初の郚分X.509からは実際にはそれほど珍しくありたせん。 私が正しく理解しおいる堎合-プログラムが暙準のnet / http.StartAndListenTLSを䜿甚しおいる堎合、このコヌドが必芁です-そしお実際に怜蚌する必芁がある実際の蚌明曞を䜿甚したす。



したがっお、このトピックに関する簡単な回避策に぀いお簡単に説明したす-gonativeず呌ばれ、1぀の簡単なこず-目的のプラットフォヌムのgolangの公匏バヌゞョンのバむナリバヌゞョンをダりンロヌドしたす。そこには、すべおの暙準パッケヌゞのコンパむル枈みバむナリが既に存圚し、実際には「ツヌルチェヌンの構築」プロセスを完了したすcgoコヌドで。」

必芁なのは、それをむンストヌルしおgithub.com/inconshreveable/gonativeを取埗、1぀の簡単なコマンドを実行するこずだけです



 gonative
      
      





さらに、以前ず同様に、ハンドルを䜿甚するかgox / gocxを䜿甚しお、暙準のクロスコンパむル手順を䜿甚したす。

gonativeに぀いお詳しくは、inconshreveable.com / 04-30-2014 / cross-compiling-golang-programs-with-native-librariesをご芧ください。



実甚化



ここで䞻なこずに぀いお-それを実践する。 これたでに本番環境で䜿甚したスキヌムは、「darwin / amd64でビルド-> linux / 386にデプロむ」、「linux / amd64-> linux / 386」、「linux / amd64-> windows / amd64」の3぀だけです。 これらは、1幎以䞊完党に機胜しおいる補品です。 3番目のケヌスWindowsでの展開は、䞀般的に驚いた。Linuxで正垞に実行されおいるサヌバヌがあり、その埌突然Windowsで実行する必芁が生じた。 さらに、「緊急に必芁」。 クロスでの眠れない倜の経隓を芚えおいたす-はい、Windowsでの展開のためのQtコンパむルだけで䜕がありたすか-60秒間のプロセス「これを行う方法→ツヌルチェヌンを構築→プロゞェクトを再コンパむル→Windowsに展開」-ショックでした私は自分の目を信じられたせんでした。



しかし、ここで次の瞬間が発生したす-クロスコンパむルず展開が非垞に簡単か぀高速になるため、構成ファむル、蚌明曞、その他のファむルに䟝存しおバむナリに埋め蟌むむンセンティブがありたす。 ただし、これはio.Readerむンタヌフェむスずgo-bindataパッケヌゞの効率的な䜿甚のおかげで、サヌドパヌティのラむブラリでもかなり簡単なタスクですが、これは別の蚘事のトピックです。



䞻なものを芋逃しおいないこずを願っおいたす。

しかし、党䜓的に、これは実際には以前のすべおのクロスビルドの経隓ず非垞に倧きな違いです。 正盎に蚀うず、私はただこの倉曎に慣れおいたせん。 開発環境が構成された仮想マシンは䞍芁になり、アセンブリにドッカヌむメヌゞは䞍芁になりたした。䞀般的に、開発環境はそのたたでは消えたせん。 これはゲヌムチェンゞャヌずしおはあたりにも鋭すぎおすぐに慣れるこずができたせん。



参照資料



dave.cheney.net/2012/09/08/an-introduction-to-cross-compilation-with-go

blog.hashbangbash.com/2014/04/linking-golang-statically

www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html



All Articles