※この記事はUdon Advent Calendar 2024 - Adventarの24日目の記事です。
はじめに
この記事でUbuntuサーバにおいて独自コマンドを定義する方法を紹介しましたが、肝心の中身の作り方は解説していませんでした。
コマンドとして利用できるファイルには以下のようなものがあります。
- シェルスクリプト
- 実行形式ファイル
前者はコマンドを羅列することによって作成することができます。Windowsで言うところのバッチファイルです。内容もコマンドそのものなので人間にも読むことができ、作成も比較的容易です。
問題は後者です。
なので、ここでは実行形式ファイルをいろいろな方法で作ってみた様子を紹介しようと思います。
そもそも実行形式ファイルとは
バイナリファイルともいい、コンピュータが直接実行できる形式のファイルです。Windowsで言うところのexeファイルです。
Linuxでは拡張子がないことが多いですね。
このファイルの中身をtype
やらcat
で見ても、意味不明な文字列しか出てきません。これは機械語が書かれているためです。ところどころ意味の分かる文字列はありますが、全体的には意味不明です。文字コードがおかしいものもあります。
人間が読めない代わりに、コンピュータによる閲覧に最適化されているので、高速に実行することができるという利点があります。
作成方法
ではどんなことをすると実行形式ファイルは作成されるのでしょうか。普通にプログラミングしてできるファイルは人間が読めるので、実行形式ファイルではありません。しかし、それをコンパイルすることによって実行形式ファイルが作成されるわけです。
それではやってみます。アセンブリ言語以外は以下のような環境を想定しています。
- Linux
- gccインストール済
- g++インストール済
- makeインストール済
アセンブリ言語の場合、WindowsにMASMがインストールされていることを想定しています。
C言語でプログラミング→コンパイル
まずはC言語で適当にプログラムを書いてみます。
#include <stdio.h>
int main(){
printf("Hello, World!\n");
return 0;
}
このファイルをhello.c
として保存し、以下のコマンドでコンパイルします。
$ gcc -o hello hello.c
これでhello
という実行形式ファイルが作成されました。
$ ./hello
Hello, World!
gcc
はコンパイラの名前です。-o
オプションは出力ファイル名を指定するものです。hello
という名前を指定しているので、hello
という実行形式ファイルが作成されます。その名前をコマンドの要領で叩くことで、プログラムが実行されます。
ちなみに、-o
オプションを指定しない場合、デフォルトでa.out
という名前の実行形式ファイルが作成されます。
$ gcc hello.c
$ ./a.out
Hello, World!
これだと不便なので、-o
オプションを使うことが一般的です。
ちなみに、上述のhello
の中身を見てみると、以下のようになっています。
makeファイルを使ってみる
コンパイルの際に様々なオプションがある場合、いちいちコマンドを打つのは面倒です。そこで、makeファイルを使ってみましょう。
makeファイルはコンパイルの手順を記述しておくことができるファイルです。これを使うことで、コンパイルの手順を一括で行うことができます。
以下のようなファイルを名前をMakefile
として作成します。
hello: hello.c
gcc -o hello hello.c
まずルール名を指定し、コロンのあとに対象のCファイルの名前、そのあとにインデントしつつコンパイルのコマンドを書きます。
これを保存して、make
コマンドを実行します。
$ make
gcc -o hello hello.c
これでhello
という実行形式ファイルが作成されました。
$ ./hello
Hello, World!
makefile内にはいくつかのルールをまとめて書くこともできます。
hello: hello.c
gcc -o hello hello.c
goodbye: goodbye.c
gcc -o goodbye goodbye.c
この場合、make
のあとにルール名を指定することで使い分けを行います。
$ make hello
gcc -o hello hello.c
$ make goodbye
gcc -o goodbye goodbye.c
Makefile
を編集することにより、柔軟にコンパイル方法を変更することができるほか、いくつかの依存関係のあるファイルを一括でコンパイルし、一つの実行形式ファイルにまとめることも可能です。
C++でプログラミング→コンパイル
C++もCと同様実行の前にコンパイルが必要です。
#include <iostream>
using namespace std;
int main(){
cout << "Hello, World!" << endl;
return 0;
}
このファイルをhello.cpp
として保存し、以下のコマンドでコンパイルします。
$ g++ -o hello hello.cpp
これでhello
という実行形式ファイルが作成されました。
$ ./hello
Hello, World!
アセンブリ言語をアセンブル+リンク
この記事に書いてあります。
アセンブリは機械語に近いわけですが、完全に機械語というわけではないのでやはりコンパイルが必要です。
まとめ
様々な方法で実行形式ファイルを作ることができました。これらの方法は全体のごく一部であり、非常に簡略化されているものです。