nmakeを使ってみよう

LLVM Clangを使っているときは、ビルドツールとしてGNU makeを使用した。今回のケースでLLVM Clangでビルドすることを前提とした場合は、次のようなMakefileを用意してGNU makeで使うことになる。

GNU make 用の Makefile

CMD=    helloworld.exe

SRCS=   $(wildcard *.c)
OBJS=   $(SRCS:.c=.o)

CC= clang
CFLAGS+=-g
EXIST=  cmd.exe //C if exist

build: $(CMD)

$(CMD): $(OBJS)
    $(CC) $(CFLAGS) -o $(CMD) $(OBJS)

.c.o:
    $(CC) -c $< -o $@

clean:
    $(EXIST) $(CMD) del $(CMD)
    $(EXIST) main.o del $(OBJS)
    $(EXIST) $(CMD:.exe=.ilk) del $(CMD:.exe=.ilk)
    $(EXIST) $(CMD:.exe=.pdb) del $(CMD:.exe=.pdb)
    $(EXIST) $(CMD).stackdump del $(CMD).stackdump
    $(EXIST) nul del *.tmp nul

Microsoft C/C++でも同じようにGNU makeを使ってもよいのだが、MicrosoftはnmakeというMicrosoftのmakeを持っている。Visual Studio Build Tools 2022をインストールして使うのだから、ビルドシステムとしてnmakeを使ってみよう。GNU makeのような拡張機能はないが、基本的にはmakeそのものだ。

先ほどのGNU make向けMakefileをMicrosoft nmake向けに書き換えると、次のようになる。

Microsoft nmake 用の Makefile

CMD=    helloworld

CC= cl.exe
CFLAGS= /c

LINK=   link.exe
LIBS=   
LFLAGS=

EXIST=  cmd.exe /C if exist

all: build

build: $(CMD).exe

$(CMD).exe: $(CMD).obj
    $(LINK) $(LFLAGS) $(LIBS) *.obj
    dir

.c.o:
    $(CC) $(CFLAGS) $*.c

clean:
    $(EXIST) $(CMD).obj del *.obj
    $(EXIST) $(CMD).exe del $(CMD).exe
    dir

実行すると、次のようになる。

  • nmake 用の Makefile と nmake コマンドの実行例

    nmake 用の Makefile と nmake コマンドの実行例

ここまでに説明してきたような操作がVisual Studio Build Toolsを使う場合の最も基本的なコマンドの使い方ということになる。Visual Studioといった統合開発環境を使うと、環境変数の設定やビルド指定などさまざまな部分を統合開発環境側が補佐してくれる。補佐してくれない場合の使い方が今回のサンプルということになる。

巨大な複雑なソフトウェアであったとしても、基本的にはこうした基本的なコマンドの組み合わせでビルドされている。小さなソースコードを使ってこうした基本的な部分の動きを知っておくと、ビルドに問題が出たときや、別のプラットフォームに移植するときなどの問題解決に役立つことがある。

参考