よく使うかも知れないリンカオプションのまとめ。
対象:Visual C++ 2008 Express Edition
> cl Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. > link Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved.
まだリンカオプションを駆使するような場面に遭遇していないので、極々簡単で良く使いそうなものだけをまとめた。
DLL関連については別ページでまとめておく。
出力ファイル名のデフォルトは、コマンドラインで最初に指定された".obj"ファイルのbasenameに".exe"/".dll"を付けたものになる。
> LINK foo.obj bar.obj baz.obj → foo.exe が生成される。
"/OUT:filename"により、出力ファイル名を指定出来る。
> LINK /OUT:main.exe foo.obj bar.obj baz.obj → main.exeが生成される。
実行可能ファイルの環境を指定する。他にもBOOT_APPLICATION, NATIVEなどあるが、さしあたり必要なのはCONSOLEとWINDOWSの2種類。
サブシステムの選択により、エントリポイントが決まる。
win32_console.c:
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, World!\n"); return 0; }
コンパイル:
> cl /c win32_console.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. win32_console.c
"/SUBSYSTEM"無しでリンクしてみる:
> link win32_console.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. > win32_console.exe Hello, World!
DUMPBINでサブシステムを確認してみると、"subsystem"が確かに"Windows CUI"になっている:
> dumpbin /headers win32_console.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 3 subsystem (Windows CUI) (...)
"/SUBSYSTEM:CONSOLE"と明示的にリンクしてみる:
> link /SUBSYSTEM:CONSOLE win32_console.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. > win32_console.exe Hello, World!
DUMPBINコマンドで確認してみると、"subsystem"が確かに"Windows CUI"になっている:
> dumpbin /headers win32_console.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 3 subsystem (Windows CUI) (...)
続いて、わざと "/SUBSYSTEM:WINDOWS" を指定してみると"WinMain"関数が見つからずにエラーとなる。
> link /SUBSYSTEM:WINDOWS win32_console.obj Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. LIBCMT.lib(wincrt0.obj) : error LNK2019: \ 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。 win32_console.exe : fatal error LNK1120: 外部参照 1 が未解決です。
win32_gui.c:
#include <windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBoxA( NULL, "Hello, Win32 GUI Applications!", "Hello, World!", MB_OK); return 0; }
コンパイル:
> cl /c win32_gui.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. win32_gui.c
まずは"/SUBSYSTEM"無しでリンクしてみる:"WinMain"があるので、"/SUBSYSTEM:WINDOWS"がデフォルトで選択される。
> link win32_gui.obj user32.lib Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved.
DUMPBINでサブシステムを確認してみると、"subsystem"が確かに"Windows GUI"になっている:
> dumpbin /HEADERS win32_gui.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 2 subsystem (Windows GUI) (...)
明示的に"/SUBSYSTEM:WINDOWS"を指定してリンクしてみる:
> link /SUBSYSTEM:WINDOWS win32_gui.obj user32.lib Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved.
DUMPBINでサブシステムを確認してみると、"subsystem"が確かに"Windows GUI"になっている:
> dumpbin /HEADERS win32_gui.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 2 subsystem (Windows GUI) (...)
わざと "/SUBSYSTEM:CONSOLE" を指定してみると、"main"関数が見つからないのでエラーとなる:
> link /SUBSYSTEM:CONSOLE win32_gui.obj user32.lib Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. LIBCMT.lib(crt0.obj) : error LNK2019: \ 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。 win32_gui.exe : fatal error LNK1120: 外部参照 1 が未解決です。
win32_guicon.c:
#include <windows.h> #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, World!\n"); return 0; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBoxA( NULL, "Hello, Win32 GUI Applications!", "Hello, World!", MB_OK); return 0; }
コンパイル:
> cl /c win32_guicon.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. win32_guicon.c
"/SUBSYSTEM"無しでリンクしてみると、"CONSOLE"が仮定された旨の警告が表示される:
> link win32_guicon.obj user32.lib Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. LINK : warning LNK4031: サブシステムが指定されていません。CONSOLE を仮定します。 > win32_guicon.exe Hello, World!
DUMPBINで確認してみると、"subsystem"が"Windows CUI"になっている:
> dumpbin /headers win32_guicon.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 3 subsystem (Windows CUI) (...)
"/SUBSYSTEM:WINDOWS"を指定してリンクしてみる:
> link /SUBSYSTEM:WINDOWS win32_guicon.obj user32.lib Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved.
実行してみるとメッセージボックスが表示され、WinMain()の方が動作したことが分かる。
DUMPBINで確認してみると、"subsystem"が"Windows GUI"になっている:
> dumpbin /headers win32_guicon.exe Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. (...) OPTIONAL HEADER VALUES (...) 2 subsystem (Windows GUI) (...)