UNIX向けソフトウェアをMinGWに移植する際のテクニック
UNIX向けソフトウェアをMinGWに移植する
最近MinGWのクロスコンパイラを使ってcurlppとspidermonkeyのビルドができるようになった。これはつまり、もともとLinux/Mac/MSVC向けでしか動かなかったものをMinGWでビルドできるようにしたということである。その時使用した小手先テクニックを述べる。
MSVC向けルートは壊さない
MinGWはPOSIX互換ではない。Cygwinにはあるのに、MinGWには無いヘッダファイルが結構ある。既存のコードにMSVCでビルドするルートができている場合、コンパイル時はそこをMinGWに走らせる形が望ましい。
具体的な方法としては、下のようなconfigure.acを書いてMinGWのコンパイラが使う定数値をMSVCが使っているものに誘導する。
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.67]) AC_INIT([hoge], [1.0.0], [hogehoge@fuga-mail.com]) AC_CANONICAL_TARGET ← ここ重要 (省略) # Checks for HostOS ← ここでホストのOSを判断して分岐させる case "$host" in *-*-mingw*) ← ここで使いたい定数値を決めてしまう ;; *-*-cygwin*) ;; *-*-linux*) ;; *-*-darwin*) ;; *-*-solaris*) ;; *-*-freebsd*) ;; *) AC_MSG_WARN([*** Please add $host to configure.ac checks!]) ;; esac
リンク時はUNIX形式に従う
前のエントリで述べたように、MinGWでdllを作成する場合はdllimportやdllexportなどのVC++独自の仕様が邪魔になる(Importing inline functions in MinGW - なんとな~くしあわせ?の日記)。だからリンク時はコンパイラが、UNIX向けルートを見るように誘導する。
MinGW32とMinGW64はそれぞれコンパイラのプリプロセッサとして以下を定義している
# MinGW32 __MINGW32__ # MinGW64は __MINGW32__と__MINGW64__のどちらも定義する __MINGW32__ __MINGW64__
参考:MinGW - Dev - Macros __MINGW32__ AND __MINGW64__
それを使って、Windowsのリンク時の設定でdllexportやdllimportの設定を行うルートに誘導しようとするところを改変する。
// もともとのコード #ifdef WIN32 // MSVCのdllexport, dllimportの設定 #else // UNIX向け #endif // 改変後のコード #if defined(WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__) // MSVCはこっちに入る #else // MinGW32, 64はこっちに入る #endif
まあそんな感じです