· 

WSLでWindows実行ファイルを作るまでの地味な道のり(1)

 

WSLでMinGWを使って、C言語で32bitおよび64bitのWindows実行ファイルを作るっていう、もうあっちこっちで復習が繰り返されているテーマを敢えて復習してみる。

WSLはここhttps://learn.microsoft.com/ja-jp/windows/wsl/installに書いてある通り、管理者権限のコマンドプロンプトからwsl --installってするだけでディストリビューションまでインストールされる。
ディストリビューションを選びたい場合はこちらhttps://learn.microsoft.com/ja-jp/windows/wsl/install-manualに従う。
まぁ一度wsl --installってして、wsl --unregister Ubuntuでディストリビューションをアンインストールて、その後、好みのディストリビューションをStoreからインストールするって手もあるんじゃない?
で、Ubuntuがインストールされているとして進める。

まずはproxy内にあるPCでWSLを使う場合、インストールしたディストリビューションにproxyを教えないといけない(これをしないとsudo apt *もできないので)。
[apt用のproxy設定]
/etc/apt/apt.conf
ってファイルを作る。内容は、
Acquire::http::Proxy "http://サーバー名:ポート番号";
Acquire::https::Proxy "http://サーバー名:ポート番号";
とする。
なお、このファイルを作るにはroot権限(WindowsでいうところのAdministrator権限)が必要なので、
viエディタを使う場合には
sudo vi /etc/apt/apt.conf
ってする。Linuxになじみのない人はnanoを使う方がいいかも。
sudo nano /etc/apt/apt.conf

[全般的なproxy設定(環境変数)とgit用の設定]
~/.bashrc
の最後に
export ftp_proxy=http://サーバー名:ポート番号
export http_proxy=http://サーバー名:ポート番号
export https_proxy=http://サーバー名:ポート番号
export FTP_PROXY=http://サーバー名:ポート番号
export HTTP_PROXY=http://サーバー名:ポート番号
export HTTPS_PROXY=http://サーバー名:ポート番号
git config --global http.proxy ${HTTP_PROXY}
git config --global https.proxy ${HTTPS_PROXY}
git config --global url."https://".insteadOf git://
を追加する。ちなみに最後の行が必要なのかどうかはわからん。
"~"は自分のホームフォルダのこと。
~/.bashrcは自分の所有物なので、sudoは不要。
で、これを有効にするために
source ~/.bashrc
ってするか、一旦ログアウト
logout
する。

ここまできたら、aptのデータベース更新とインストール済みアプリの更新を行う。
sudo apt update
sudo apt -y upgrade
以降のアプリのインストールにもaptコマンドを使うのが通なんだけど、Windowsにかぶれてしまっている人はsynapticを使う。
sudo apt -y install synaptic
で、完了したら
sudo synaptic
ってすると、こういうのが出る。

何書いているかわからんが"Close"しか押せないので"Close"を押す。
こうなる。
Searchを押す。
build-essential
と入力して
"Search"を押す。
こうなる。
build-essentialの左にあるボックスをクリックする。
こうなるので、"Mark for Installation"を押す。
こういうのが出てくる。関連するアプリ等を全部選択してくれる。ので、"Mark"を押す。
次は"mingw"を検索する。で、出てきた結果から、"mingw-w64"を探して同じくMarkする。
こうなる。上のほうにスクロールすると、gccとg++も選択されていることがわかる。
で、Applyを押す。
すると、こういうのが出るので、やはりApplyを押す。
そして、ひたすら待つ。
意外とすぐに終わる。

で、Close。
で、×おしてsynapticを終了する。

wslのシェル(windowsでいうコマンドプロンプト画面)で作業用のフォルダを作成して、そこに移動します。
mkdir -p work/gcc/dllstudy1
cd work/gcc/dllstudy1

で、VSCodeを起動します。
code .
WindowsにVSCodeがインストールされていればwslでVSCodeを起動することができます。
こうなる。
当然"Yes ..."を押す。
VSCodeの拡張機能をインストールする。この辺https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscodeを参考に。
うちの場合はwslに関連しそうなのはこいつらが入っている。

うちの場合は、sshでがちLinuxに入るって使い方もしているから、wslだけってなら要らんものも入っているかも。
VSCodeでは使っている間にその場面に応じて使えそうな拡張機能を教えてくれるので基本的にはそれに従えばいい。
こんなかんじで右下になにか出る。


で、今回のdllの機能は、、、例題なので、
2つの引数a,bから、a^2+bを戻すものとする。引数も戻り値も32bit符号なし整数とする。
で、2乗するコードを不必要に分割して、例題としてほんの少し現実のプロジェクトに近づける。あまりにもシンプルな例題だと応用までの距離が遠すぎてしんどい、と、世の中の例題を見ていて思っていたので。ていうか、Windows実行ファイルといいながら、いきなりdllを作成するってのがそもそもマニアック。
で、以下のファイルを作成する
Makefile
study1.cpp
tasu.c
nijo.c
study1.def
まぁ内容はたいしたことにはならないはず。
では、じゃんじゃんやっていきまっす。

ちなみにVSCodeでファイルを作るにはこれを押す。


Makefile
TARGETNAME=study1
CC=/usr/bin/i686-w64-mingw32-gcc
CXX=/usr/bin/i686-w64-mingw32-g++
LINK=/usr/bin/i686-w64-mingw32-gcc
CFLAGS= -Wall -c
LFLAGS= -o $(TARGETNAME).dll -shared -static-libgcc -static-libstdc++
OBJS= $(TARGETNAME).o nijo.o tasu.o

ALL : $(TARGETNAME).dll

$(TARGETNAME).dll : $(OBJS)
        $(LINK) $(LFLAGS) $(OBJS) $(TARGETNAME).def

.cpp{}.obj :
        $(CXX) $(CFLAGS) $<

.c{}.obj :
        $(CC) $(CFLAGS) $<

clean :
        rm $(OBJS) $(TARGETNAME).dll


study1.cpp
#include <stdint.h>

/*Cで作成された別のファイルにある関数のプロトタイプ宣言*/
extern "C"{
    extern uint32_t nijo(uint32_t a);
    extern uint32_t tasu(uint32_t a,uint32_t b);
}

extern "C" uint32_t __stdcall keisan(uint32_t a,uint32_t b){
    return tasu(nijo(a),b);
}


tasu.c
#include <stdint.h>

uint32_t tasu(uint32_t a,uint32_t b){
    return a+b;
}


nijo.c
#include <stdint.h>

uint32_t nijo(uint32_t a){
    return a*a;
}


study1.def
LIBRARY study1
EXPORTS
    keisan

では、Makeしてみる。

VSCodeでTerminalを表示させる。

でMake

そして

できた。

テストする前に、dependencies(https://github.com/lucasg/Dependencies)でkeisanって関数がちゃんとエクスポートされているか見てみる。
wsl内のファイルには普通にエクスプローラでアクセスできるので、ここからDependenciesGUIの画面にドロップすればいい。


とりあえず、ここまではうまくいっている。(つづく)

Google-code-prettifyで行番号が表示されなくなってるー。過去の記事でも表示されなくなっているからGoogle側の問題だろう。いつか解決すると信じてそうっとしておく。