👩‍🚒

ライブラリからビルドするHello World(FreeDOS版)

2022/01/04に公開

はじめに

以前smallercを使用して、FreeDOS版のプログラムの作成を行いました。
https://zenn.dev/saitoyutaka/articles/d65d4894567efd

Hello Worldをビルドしたときにリンク時にlcds.aをリンクしています。

$ smlrcc -v -dost -IPATH/SmallerC/v0100/include -SLPATH/SmallerC/v0100/lib -o hello.com hello.c
smlrpp -U __STDC_VERSION__ -zI -D _DOS -I PATH/SmallerC/v0100/include -D __SMALLER_C__ -D __SMALLER_C_16__ -D __SMALLER_C_SCHAR__ -D __SMALLER_C_UWCHAR__ -D __SMALLER_C_WCHAR16__ -D __SMALLER_PP__ -o hello.i hello.c
smlrc -seg16 -nopp hello.i hello.asm
nasm -f elf hello.asm -o hello.o
smlrl -tiny hello.o PATH/SmallerC/v0100/lib/lcds.a -o hello.com ★ここ

今回はlcds.aを自前でビルドしてみます。

Hello worldに必要なもの

以下のようなコードを用意します。

hello.c
#include <stdio.h>

int main(){
    printf("Hello FreeDOS 2022\n");
    return 0;
}

必要なライブラリをビルドはどれか

ぱっと思いつくのはprintfです。

smallercではprintfは以下のようになっています。
https://github.com/alexfru/SmallerC/blob/master/v0100/srclib/printf.c#L7

printfの中で__doprintを呼んでいます。
__doprintのコードは以下。

https://github.com/alexfru/SmallerC/blob/2a180411235df39bc9df7782b00ed199bedb1fd8/v0100/srclib/doprint.c#L262

__doprint の中で__fputcを呼んでいてこのコードは・・・
というように必要なコードを探します。

で、必要なファイルの一覧は以下になります。

$ ls *.c *.asm
c0.c      ctype.c    fclose.c    fputc.c  isdigit.c  remove.c  stdio1.c  strlen.c   write.c
c0ds.asm  doprint.c  fflush.c    free.c   malloc.c   stderr.c  stdout.c  toupper.c
close.c   exit.c     flushbuf.c  printf.c   stdin.c   strchr.c  unlink.c

なんで、Hello Worldだけでこんなに必要なのよ、と思うかと思いますが
理由は省略(今度書きます)。

Makefileの作成

必要なファイルがわかったので、
Makeコマンドでビルドできるようにしてみます。
以下のようなMakefileを作成しました。

Makefile
.SUFFIXES:

MYPATH=★ここにルートパスを書く
INCLUDE=$(MYPATH)SmallerC/v0100/include
OBJS=hello.o c0ds.o c0.o ctype.o isdigit.o close.o unlink.o stdio1.o stdin.o flushbuf.o stdout.o stderr.o toupper.o remove.o fflush.o fclose.o write.o fputc.o doprint.o printf.o exit.o strchr.o strlen.o malloc.o free.o
SRCPATH=$(MYPATH)SmallerC/v0100/srclib/

DEFINES=-D __SMALLER_C__ -D __SMALLER_C_16__ -D __SMALLER_C_SCHAR__ -D __SMALLER_C_UWCHAR__ -D __SMALLER_C_WCHAR16__ -D __SMALLER_PP__

%.i:%.c
	smlrpp -U __STDC_VERSION__ -zI -D _DOS -I $(INCLUDE) $(DEFINES) -o $@ $<

%.asm: %.i
	smlrc -seg16 -nopp $< $@

%.o: %.asm
	nasm -f elf $< -o $@

hello.com: $(OBJS)
	smlrl -tiny $(OBJS) -o hello.com

.PHONY: all clean
clean:
	rm hello.com *.o *.i *.asm
	rm printf.c
	rm doprint.c
	rm c0.c
	rm exit.c
	rm stdin.c
	rm stdout.c
	rm stderr.c
	rm toupper.c
	rm fclose.c
	rm fflush.c
	rm close.c
	rm remove.c
	rm free.c
	rm malloc.c
	rm unlink.c
	rm write.c
	rm stdio1.c
	rm fputc.c
	rm isdigit.c
	rm strchr.c
	rm strlen.c
	rm ctype.c
	rm flushbuf.c
	rm idos.h
	rm ictype.h
	rm istdio.h
	rm mm.h
	rm c0ds.asm

all:
	cp $(SRCPATH)printf.c .
	cp $(SRCPATH)doprint.c .
	cp $(SRCPATH)c0.c .
	cp $(SRCPATH)exit.c .
	cp $(SRCPATH)stdin.c .
	cp $(SRCPATH)stdout.c .
	cp $(SRCPATH)stderr.c .
	cp $(SRCPATH)toupper.c .
	cp $(SRCPATH)fclose.c .
	cp $(SRCPATH)fflush.c .
	cp $(SRCPATH)close.c .
	cp $(SRCPATH)remove.c .
	cp $(SRCPATH)free.c .
	cp $(SRCPATH)malloc.c .
	cp $(SRCPATH)unlink.c .
	cp $(SRCPATH)write.c .
	cp $(SRCPATH)stdio1.c .
	cp $(SRCPATH)fputc.c .
	cp $(SRCPATH)isdigit.c .
	cp $(SRCPATH)strchr.c .
	cp $(SRCPATH)strlen.c .
	cp $(SRCPATH)ctype.c .
	cp $(SRCPATH)flushbuf.c .
	cp $(SRCPATH)idos.h .
	cp $(SRCPATH)ictype.h .
	cp $(SRCPATH)istdio.h .
	cp $(SRCPATH)mm.h .
	cp $(SRCPATH)c0ds.asm .
	make hello.com

hello.comの作成

適当なディレクトリを作って上記のMakefileとhllo.cを置きます。

$ ls
Makefile hello.c

make allで実行ファイル(hello.com)が作成されます。

$ make all
$ file hello.com 
hello.com: DOS executable (COM)

まとめ

ライブラリ(lcds.a)を使用せずに、全て自分でビルドして
プログラムの作成ができました。
個別にコンパイルしたファイルの中身については次回以降(?)説明します。

Discussion