====== GNUstep Make ======
[[gnustep:|{{:gnustep:gnustep_logo.svg?150|GNUstep logo}}]]
GNUstepは、GNU MakeのMakefileのコレクションによる、独自のビルドツールを提供しています。
* https://github.com/gnustep/tools-make
このビルドツールをGNUstep Makeと呼ぶことにします。
いくつかの簡単なルールを覚えてしまえば、手動で直接Objective-Cコンパイラを実行したり、自前のMakefileを書いたりする手間が大幅に省けるようになります。
たとえ単純なHello Worldプログラムであっても、直接Objective-Cコンパイラを呼び出すよりも、GNUstep Makeを利用する方が楽ができます。
したがって、Objective-C+GNUstepのプログラミングを続けるのに次に越えなければならないハードルは、GNUstep Makeのルールを覚えることであると言えます。
===== Ubuntu 24.04 LTS =====
パッケージgnustep-makeがインストールされていることを確認します。
このパッケージはgnustep-develをインストールした場合、同時にインストールされています。
gnustep-makeには、GNUstep Makeの環境をアクティブにするスクリプトが含まれています。
そのシェルスクリプトを現在のシェルにソースすることで、GNUstep Makeが利用可能な状態になります。
$ source /usr/share/GNUstep/Makefiles/GNUstep.sh
GNUstep自体をソースからインストールした場合は、/usr/local/share/GNUstep/Makefiles/GNUstep.shなどに配置されています。
シェルを立ち上げるたびに毎回このコマンドを実行する必要があります。
それほど長いコマンドではありませんが、面倒であればシェルのaliasを設定しておくと良いです。
$HOME/.bashrcなどに次の1行を追加しておきます。
alias gnustep-make-activate='source /usr/share/GNUstep/Makefiles/GNUstep.sh'
どのように使うかは、実例を見てみたほうが早いと思うので、そうします。
===== 例1: Hello World =====
[[helloworld|以前やったHello Worldプログラム]]をGNUstep Makeを使ってビルドしてみます。
まず新たに適当な名前のディレクトリを作ります。
その中にhello.mという名前のObjective-Cのソースファイルを作成します。
__hello.m__:
#include
int main(void)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Hello, world!");
[pool release];
return 0;
}
同じディレクトリにGNUmakefileという名前のファイルを作成します。
__GNUmakefile__:
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = HelloWorld
HelloWorld_OBJC_FILES = hello.m
include $(GNUSTEP_MAKEFILES)/tool.make
少し注意を払って内容を見てみます。
* common.makeというMakefileをインクルードしている
* ''TOOL_NAME''という変数に''HelloWorld''とセットしている
* ''TOOL_NAME''にセットした名前に続けて''_OBJC_FILES''と加えた名前の変数に、Objective-Cのソースファイルをセットしている
* tool.makeというMakefileをインクルードしている
まずTOOLとは何かと疑問に思われることかと思います。
これはプロジェクトのタイプを意味しています。
TOOLはコマンドラインツール(GUIではない)を意味しています((実際にはコマンドラインツールであってもGUIアプリケーションとしてビルドすることができるので、この分類の仕方はあまり正確ではありません。))。
コマンドラインツールであるならば、''TOOL_NAME''をセットした上で、tool.makeをインクルードすることをGNUstep Makeが要求しています。
プロジェクトの種類は全部で16種類あり、コマンドラインツールはそのうちの一つです。
プロジェクトの種類に関する情報はどこで見つければよいのかというと、[[https://www.gnustep.org/resources/documentation/Developer/Make/Manual/gnustep-make.html|マニュアルが存在するのでこれがヒントになるかもしれません]]。
ただし、すべての情報が書かれているわけではないので、最悪の場合、GNUstep Makeが提供するMakefileの中身を直接確認する必要に迫られることがあるかもしれません。
GNUstep Makeの構成は非常に複雑ですので、時間を浪費しないためにも今の段階ではあまり深入りしないことをおすすめします。
この時点でソースツリーは次のようになっているとします。
HelloWorld/
├── GNUmakefile
└── hello.m
HelloWorldディレクトリの中で''make''を実行します。
$ make
This is gnustep-make 2.9.1. Type 'make print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for tool HelloWorld...
Compiling file hello.m ...
Linking tool HelloWorld ...
objというディレクトリの中に実行可能バイナリファイルが生成されています。
HelloWorld/
├── GNUmakefile
├── hello.m
└── obj
├── HelloWorld ←生成された実行可能バイナリファイル
└── HelloWorld.obj
├── hello.m.d
└── hello.m.o
実行するには''obj/HelloWorld''とタイプします。
$ obj/HelloWorld
2025-05-21 06:48:48.697 HelloWorld[18696:18696] Hello, world!
これで完了です。
===== 例2: Hello Panel =====
今度はプロジェクトのタイプがGUIアプリケーションのプロジェクトを作成してみます。
先のGNUMakefileからの変更点は次の2点です。
* ''TOOL_NAME'' -> ''APP_NAME''
* ''tool.make'' -> ''application.make''
Objective-Cのソースコードは変更しなくてもいいのですが、せっかくなのでGUIアプリケーションらしいものに変更してみます。
適当な名前の新しいディレクトリを作成して、その中に次の2つのファイルを作成します。
hello.m (([[https://home.gnustep.org/nicola/Tutorials/WritingMakefiles/node6.html|こちらのチュートリアル]]から拝借して若干の変更を加えました。)):
#import
#import
int main(void)
{
NSAutoreleasePool *pool;
pool = [NSAutoreleasePool new];
[NSApplication sharedApplication];
NSRunAlertPanel(@"Hello Panel", @"Hello from the GNUstep AppKit", nil, nil, nil);
[pool release];
return 0;
}
__GNUmakefile__:
include $(GNUSTEP_MAKEFILES)/common.make
APP_NAME = HelloPanel
HelloPanel_OBJC_FILES = hello.m
include $(GNUSTEP_MAKEFILES)/application.make
この時点でソースツリーは次のようになります。
HelloPanel/
├── GNUmakefile
└── hello.m
HelloPanelディレクトリの中で''make''を実行します。
$ make
This is gnustep-make 2.9.1. Type 'make print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for app HelloPanel...
Creating HelloPanel.app/....
Compiling file hello.m ...
Linking app HelloPanel ...
Creating HelloPanel.app/Resources...
Creating stamp file...
Creating HelloPanel.app/Resources/Info-gnustep.plist...
Creating HelloPanel.app/Resources/HelloPanel.desktop...
HelloPanel.appとobjの2つのディレクトリが作成されます。
ソースツリーの状態は次のようになっています。
HelloPanel/
├── GNUmakefile
├── HelloPanel.app
│ ├── HelloPanel
│ ├── Resources
│ │ ├── HelloPanel.desktop
│ │ └── Info-gnustep.plist
│ └── stamp.make
├── hello.m
└── obj
└── HelloPanel.obj
├── hello.m.d
└── hello.m.o
例1のTOOLのときはobjディレクトリに実行可能バイナリファイルが出力されましたが、今度はHelloPanel.appディレクトリの中にあります。
このアプリケーションを実行するには、コマンドラインに直接このファイル名をタイプするのではなく、**openapp**というランチャープログラムを使います。
$ openapp ./HelloPanel.app
少し補足しておきます。
* カレントディレクトリを示す「./」は**省略できません**。 => ''openapp HelloPanel.app''では**起動しません**。
* 末尾の「.app」は省略可能です。 => ''openapp ./HelloPanel'' でも起動します。
* 末尾に「/」がついていてもOKです。 => ''openapp ./HelloPanel.app/'' でも起動します。
実行するとポップアップが表示されます。
{{:gnustep:hellopanel.png?400|Hello Panel}}