ia16-elf-gcc で cmake を使ってみた
ia16-elf-gcc で MSDOS exe を作れてるのだから、watcom 同様 cmake を使いたく。
で公開されてるやり方に倣えば ia16-elf-gcc でも cmake できたのでそのメモです。
手順
お試しの例としては、まず watcom で試した のと同じような環境を用意します。
CMakeLists.txt は
cmake_minimum_required(VERSION 3.22)
project(hello)
add_executable(hello src/hello.c)
ubuntu 22.04 環境の cmake は ver.3.22 のようで、Watcom に合わせた 3.24 だとエラーになってしまう...ので、とりあえず今回は 3.22 を設定しています。
コンパイラ設定は ia16-elf-exe-toolchain.cmake toolchain.cmake を用意します。
たのしい組み込みCMake を見様見真似で
# toolchain
set(CMAKE_C_COMPILER ia16-elf-gcc)
set(CMAKE_CXX_COMPILER ia16-elf-g++)
set(CMAKE_AR ia16-elf-ar CACHE FILEPATH "Arhiver")
set(CMAKE_RANLIB ia16-elf-ranlib CACHE FILEPATH "Ranlib")
set(CMAKE_AS ia16-elf-as)
set(CMAKE_NM ia16-elf-nm)
set(CMAKE_OBJDUMP ia16-elf-objdump)
# to pass compiler test
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# target
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR I86)
set(CMAKE_SYSROOT "/usr/ia16-elf")
set(CMAKE_INCLUDE_PATH "${CMAKE_SYSROOT}/include")
set(CMAKE_LIBRARY_PATH "${CMAKE_SYSROOT}/lib")
set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# flags
set(CMAKE_C_FLAGS "-Wall -Wextra -fno-stack-protector -static -march=i8086 -mcmodel=small ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -fno-stack-protector -static -march=i8086 -mcmodel=small ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-fnothrow-opt -fdelete-dead-exceptions -fno-rtti -fno-exceptions ${CMAKE_CXX_FLAGS}")
# Extension
set(CMAKE_EXECUTABLE_SUFFIX ".exe")
set(CMAKE_EXECUTABLE_SUFFIX_ASM ".exe")
set(CMAKE_EXECUTABLE_SUFFIX_C ".exe")
set(CMAKE_EXECUTABLE_SUFFIX_CXX ".exe")
のように作成。
cmake -DCMAKE_TOOLCHAIN_FILE=../ia16-elf-exe-toolchain.cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../
をすれば Makefile 作成、それを make でビルドできれば ok.
ここでは CMAKE_BUILD_TYPE=MinSizeRel を指定してみました。
hello 程度では意味ありませんが、 Release だと -O3 が使われ太りやすいようなので、MinSizeRel でプログラムサイズを減らす指定を選びました。
ia16-elf-exe-toolchain.cmake について
set(CMAKE_SYSROOT "/usr/ia16-elf") 等、もろに ubuntu 22.04 用の ia16-elf-gcc の環境に依存しています。
その他もそれっぽく設定してみただけ。(不要/デフォルトでよさそうなものは削除)
FLAGS はお好みで...なんだけど。
-march=i8086 -mcmodel=small をデフォルト設定とて入れています。これは、
add_compile_options(-march=i80186 -mcmodel=medium)
等、後付オプションで前の設定を上書きできる類なので。
(デフォルト設定しておなないと微妙な生成になってそうで)
まあ c++ の場合は tiny か small しか設定できないので、これでいいか、と。
C++ 専用のオプションでは "例外" は無しにしています。お好み次第ですが 16bit 86系/MSDOS でこのへんが効率的に扱えそうにも思えず。(使えなかったか使い物にならなかったか... 実装できたとしても setjump 系だろうで)
参考元から追加しているモノとしては、実行ファイル拡張子を設定しているところでしょうか。
CMakeLists.txt 側で出力ファイル名を明示しなくてもいいように、と。
ただ、set(CMAKE_EXECUTABLE_SUFFIX ".exe") では、拡張子付加できませんでした。
ググって ここ で話に出てた拡張子別の設定を試しみたら .exe がついたので、それで吉と。
あと、この例では入れていませんが、他ターゲットとの兼ね合いで CMAKE_BUILD_TYPE=MinSizeRel でなく Release でビルドして、サイズ優先したい時は
set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG" CACHE STRING "description")
set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG" CACHE STRING "description")
を追加するのも手です。
※ toolchain.cmake で変数を設定する場合、物によっては見ての通り CACHE …… も指定する必要があるようです。CMakeのツールチェインで変数を扱う際の注意点 を参考。 (しかし、どの変数が付けなきゃいけなくて、どの変数がなくていいのかよくわからない)
com ファイル生成
前記は exe 固定にしてしまったので、tiny モデルで com を作るときは別途 toolchain.cmake を用意することにします。
内容は small → tiny、".exe" → ".com" に置換しただけのものですが。
# toolchain
set(CMAKE_C_COMPILER ia16-elf-gcc)
set(CMAKE_CXX_COMPILER ia16-elf-g++)
set(CMAKE_AR ia16-elf-ar CACHE FILEPATH "Arhiver")
set(CMAKE_RANLIB ia16-elf-ranlib CACHE FILEPATH "Ranlib")
set(CMAKE_AS ia16-elf-as)
set(CMAKE_NM ia16-elf-nm)
set(CMAKE_OBJDUMP ia16-elf-objdump)
# to pass compiler test
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# target
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR I86)
set(CMAKE_SYSROOT "/usr/ia16-elf")
set(CMAKE_INCLUDE_PATH "${CMAKE_SYSROOT}/include")
set(CMAKE_LIBRARY_PATH "${CMAKE_SYSROOT}/lib")
set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# flags
set(CMAKE_C_FLAGS "-Wall -Wextra -fno-stack-protector -static -march=i8086 -mcmodel=tiny ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -fno-stack-protector -static -march=i8086 -mcmodel=tiny ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-fnothrow-opt -fdelete-dead-exceptions -fno-rtti -fno-exceptions ${CMAKE_CXX_FLAGS}")
# Extension
set(CMAKE_EXECUTABLE_SUFFIX ".com")
set(CMAKE_EXECUTABLE_SUFFIX_ASM ".com")
set(CMAKE_EXECUTABLE_SUFFIX_C ".com")
set(CMAKE_EXECUTABLE_SUFFIX_CXX ".com")
ビルドは
cmake -DCMAKE_TOOLCHAIN_FILE=../ia16-elf-com-toolchain.cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../
make
ubuntu 22.04 で cmake ver.3.24 以上を使えるように
watcom c/c++ と共通の CMakeLists.txt を書く場合は、やっぱり ver.3.24 以上が使えないと辛い... と探してみると
にやり方が公開されていました。
この方法で ubuntu 22.04 でも cmake公式(kitware)のaptリポジトリを追加でき、現行の version(3.30) の cmake が使えるようになりました。
おわりに
cmake は沼...
Discussion