FreeBASIC ソースファイルからバイナリ
executable(実行可能) ファイルを作成します。
序文:
バイナリファイルは、単にバイナリ(つまり非テキスト)形式のファイルです:
- バイナリ形式は、プラットフォーム固有の理由でファイルの内容を変換してはならないことを意味します。(たとえば、改行を \n から \r\n に置き換える)
- バイナリファイルは必ずしも実行可能である必要はありません。たとえば、 '*.dll' や '*.a' 形式にコンパイルされたライブラリはバイナリですが、実行可能ではありません。
- 実行可能ファイルは必ずしもバイナリである必要はありません。たとえば、テキスト形式のスクリプトは、オペレーティングシステムで実行可能です。
executable(実行可能) ファイルとは、実行可能なファイルのことです(ファイル自体の名前をコマンドとして書き込むことで、コマンドラインで実行できます)。
Windows では、ファイルの拡張子は、
'*.exe' を含む実行可能ファイル拡張子の固定セットの 1つである必要があります。
Unix システムでは、ファイルの "executable" フラグも設定する必要があります。
FreeBASIC は、fbc(コマンドライン・コンパイラ/リンカー)、ランタイム・ライブラリ、およびサードパーティ・ライブラリ用の FreeBASIC ヘッダーファイルで構成されています。
実行可能ファイルを生成するために、fbc は GNU binutils(アセンブラー、リンカー)を使用します。
32 ビット x86 以外のアーキテクチャ用にコンパイルする場合、fbc はアセンブリを生成するために gcc に依存します。
FreeBASIC は、FreeBASIC コンパイラ/リンカープログラム(fbc か fbc.exe)と、これが使うツールおよびライブラリを提供します:
- fbc は、FreeBASIC ソース/インクルードファイル('*.bas'/'*.bi')とオブジェクト/ライブラリファイル('*.o'/'*.a')を取得し、これらを実行可能ファイルにコンパイルするコマンドライン・プログラムです。
- fbc は通常、統合開発環境(IDE)やテキストエディタによって、ターミナルやコマンドプロンプトから、あるいは makefiles などのビルドシステムを介して呼び出されます。
- fbc 自体は、グラフィカル・コードエディタや IDE ではありません!
FreeBASIC プログラムは、デフォルトで、プラットフォームに応じて、さまざまなシステムやサポートライブラリに対してリンクされています。
それらには、FreeBASIC for DOS で使用される DJGPP ライブラリと、FreeBASIC for Windows で使用される MinGW/GCC ライブラリが含まれます。
実行可能ファイルのコンパイル、一般
fbc は、fbc ソースコードを取得し、オペレーティング・システムでロードして実行できるファイルに変換するコンパイラです。
fbc は、これをすべて単独で行うわけではありません。 いくつかの中間ファイルと他のツールを使って、この変換を完了します。
実行可能ファイルの「主」開始点
実行可能ファイルには開始点が必要です。
「主」関数または「主」開始点と呼ぶこの開始点は、実行可能ファイルに記録する必要があります。これにより、オペレーティング・システムによって実行可能ファイルがロードされたときに、オペレーティング・システムがプログラムの実行を開始する場所を認識できます。
デフォルトでは、「主」関数または開始点は、コマンドラインの、最初の基本ソースファイルの、最初の行になります:
$ fbc program.bas module1.bas module2.bas
上の例では、"program" は最初に来ているので主モジュールになり、fbc は実行可能ファイルがロードされたときに最初に実行される暗黙の「主」関数を生成します。
このデフォルトは、 '-m module' オプションで上書きして、コマンドラインで指定された最初のソースファイルではない主モジュールを指定できます:
$ fbc -m program module1.bas module2.bas program.bas
"-m program" オプションは、"program.bas" が最初に指定されていなくても、"program.bas" を主モジュールとして使うように fbc に指示します。
コンパイル・プロセスに影響を与える他のオプションが指定されていない場合、この「主」関数は fbc によって暗黙の内に生成されます。
実行可能ファイルの「主」関数は 1つだけです。 複数の「主」関数を持つことはできません。
実行可能ファイルのコンパイル過程
fbc は、基本的なソースコードをコンパイルするときに、ソースを別の形式に変換します。この形式は、最終的に実行可能ファイルを作成する他のツールで使用できます。
デフォルトで、fbc はこれらの他のツールを自動的に使います:
' .-------------------------------------.
' | COMPILER |
' '------.----------------------.-------'
' | GAS backend | GCC backend
' | |
' .------V-----. gcc .---V----.
' | ASM CODE |<-----------| C CODE |
' | .s or .asm | compiler | .c |
' '------.-----' '--------'
' | (G)AS assembler
' |
' .------V------.
' | OBJECT CODE |
' | .o or .obj |-------------.
' '------.------' |
' | (G)AR archiver |
' | |
' .-------V--------. |
' | STATIC LIBRARY | |
' | .a or .lib |---------->|
' '----------------' | (G)LD linker
' |
' |----------------------------.
' | |
' .----------V-----------. .-----------V-----------.
' | BINARY | | SHARED LIBRARY |
' | no extension or .exe | | .so or .dll or .dylib |
' '----------------------' '-----------------------'
'
'
' Extensions are Unix convention vs Windows (ld does .lib too nowadays).
' In the case of shared libs, the name for Mac deviates (.dylib).
fbc が使うすべてのステップを表示するには、コマンドラインで '-v' を指定してステップを表示します。
たとえば、win32 の場合:
$ fbc a.bas -v
FreeBASIC Compiler - Version 1.08.0 (2021-01-24), built for win32 (32bit)
Copyright (C) 2004-2021 The FreeBASIC development team.
standalone
target: win32, 486, 32bit
backend: gas
compiling: a.bas -o a.asm (main module)
assembling: D:\fb.git\bin\win32\as.exe --32 --strip-local-absolute "a.asm" -o "a.o"
linking: D:\fb.git\bin\win32\ld.exe -m i386pe -o "a.exe" -subsystem console
"D:\fb.git\lib\win32\fbextra.x" --stack 1048576,1048576 -s -L "D:\fb.git\lib\win32"
-L "." "D:\fb.git\lib\win32\crt2.o" "D:\fb.git\lib\win32\crtbegin.o" "D:\fb.git\lib\win32\fbrt0.o"
"a.o" "-(" -lfb -lgcc -lmsvcrt -lkernel32 -luser32 -lmingw32 -lmingwex -lmoldname -lgcc_eh "-)"
"D:\fb.git\lib\win32\crtend.o"
ツール:
- [ fbc ] compiler translate *.bas in to *.asm or *.c files
- [ gcc ] compiler translate *.c files in to *.asm files
- [ as ] assembler translate *.asm files in to *.o object files
- [ ld ] linker join *.o files (and other files) in to executable files
- emscripten backend has other tools
- llvm backend has other tools
- GNU assembler 32-bit backend (-gen gas):
*.bas => [ fbc ] => *.asm compile (first stage) to assembly (-r or -rr, -R or -RR)
*.asm => [ as ] => *.o assemble to object file (-c, -C)
*.o => [ ld ] => *[.exe] link to executable
- GNU assembler 64-bit backend (-gen gas64):
*.bas => [ fbc ] => *.a64 compile (first stage) to assembly (-r or -rr, -R or -RR)
*.a64 => [ as ] => *.o assemble to object file (-c, -C)
*.o => [ ld ] => *[.exe] link to executable
- GCC compiler backend (-gen gcc):
*.bas => [ fbc ] => *.c compile (first stage) to C (-r, -R)
*.c => [ gcc ] => *.asm compile (second stage) to assembly (-rr, -RR)
*.asm => [ as ] => *.o assemble to object file (-c, -C)
*.o => [ ld ] => *[.exe] link to executable
コンパイル/アセンブル/リンク・ステージを制御するオプション
fbc が中間ファイルをどう扱うか、どの時点で処理を早期に停止させるかを制御できるオプションがいくつか用意されています。
-r, -rr, -c : stop the compile / assemble process sometime before the link stage
-R, -RR, -C : keep intermediate files at compile / assemble stages then continue to next stage
-r : option overrides -rr, -RR, -c, -C
-rr : overrides overrides -c, -C
-r and -rr : behave the same if there is only one compile stage
-R and -RR : behave the same if there is only one compile stage
-r, -rr, -c : override the default behaviour of creating an implicit "main" entry point, and no "main" function is created by default.
To have a "main" entry point when using the -r, -rr, -c, options, then '-m module' option needs to be used to indicate which module should have an "main" function.
注意:
fbc バージョン 1.09.0 より前は、-gen gas64 はアセンブラー用に (.asm ではなく) .a64 ファイル拡張子を生成しました。
各モジュールの実行順序
実行可能なプログラムには、「主」エントリーポイントが必要です(ユーザーコードの主モジュール)。
オプションや実行形式を構築する方法によって、fbc は、暗黙の主関数を作成することもしないこともあります。
モジュールのコンストラクタは、主の前に実行され、モジュールのデストラクタは、主の後に実行されます。
(主モジュール以外の)他のモジュールのモジュールレベルのコードは、暗黙のモジュール・コンストラクターに入れられ、その結果、主モジュールのモジュール・レベルのコードの前に実行されます。
ただし、モジュール・レベルのコードは主モジュールにのみ含めることを推奨します。
より一般的には、すべてのモジュール・コンストラクタとモジュール・デストラクタは、その使用に関して大きな警告を付けて注意する必要があります。
対応するコードは、ユーザーコードの外部で実行されるため、fbc のエラーチェックと一部の実行時機能が期待どおりに機能しない可能性があるからです。
スタートアップ・フレームワークの概要:
-コンパイル時に、すべてのモジュール・コンストラクタ、デストラクタのアドレスの配列を作成します。
-リンク時に、配列を実行可能ファイルに格納します。
-実行時に、起動フレームワークは次のようになります:
- 配列内のすべてのモジュール・コンストラクターを呼び出します,
- メインモジュールのユーザーコードを呼び出し,
- 終了(またはエラー)時に、すべてのモジュール・デストラクタを呼び出します(通常、プログラムがどのように失敗したかによって異なります)。
参照: