パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
ソースコード(Code::BlocksのCommands onlyターゲット)

Code::BlocksのCommand onlyビルドターゲットタイプの問題点をソースコードから解析する。

本サイトCode::Blocksプロジェクトの_Dummyターゲットで利用する、Code::BlocksのCommands onlyターゲットの挙動解析にあたって参照したソースコードを示す。Commands onlyターゲットにおけるコンパイルオプションの取得、リンクのスキップ、ファイル実行を解析する。Commands onlyターゲットはTargetType列挙値ttCommandsOnlyを持ち(include\compiletargetbase.h:32)、これをフラグとして処理を選択している。

ダウンロードリンク

ソースコード(コンパイルオプションの取得)(抜粋)

Commands onlyターゲットは様々なコンパイル実行パラメータに無条件で空文字列を設定する。全てのパラメータ取得関数を示すのは控えるが、例えばCompileTargetBase::GetOutputFilename(sdk\compiletargetbase.cpp:164)などである。

wxString CompileTargetBase::GetOutputFilename()
{
if (m_TargetType == ttCommandsOnly)
return wxEmptyString;
if (m_OutputFilename.IsEmpty())
m_OutputFilename = SuggestOutputFilename();
return m_OutputFilename;
}
wxString CompileTargetBase::SuggestOutputFilename()
{
wxString suggestion;
switch (m_TargetType)
{
case ttConsoleOnly: // fall through
case ttExecutable: suggestion = GetExecutableFilename(); break;
...
case ttCommandsOnly: // fall through
default:
suggestion.Clear();
break;
}
wxFileName fname(suggestion);
return UnixFilename(fname.GetFullName());
}
wxString CompileTargetBase::GetWorkingDir()
{
if (m_TargetType != ttConsoleOnly && m_TargetType != ttExecutable && m_TargetType != ttDynamicLib)
return wxEmptyString;
...
}
wxString CompileTargetBase::GetObjectOutput() const
{
if (m_TargetType == ttCommandsOnly)
return wxEmptyString;
...
}
wxString CompileTargetBase::GetDepsOutput() const
{
if (m_TargetType == ttCommandsOnly)
return wxEmptyString;
...
}
...

ソースコード(リンクのスキップ)(抜粋)

[Build|Build]などによるビルドがリンク実行を要求すると、通常ならDirectCommands::GetTargetLinkCommands(plugins\compilergcc\directcommands.cpp:621)がリンクコマンドをキューに追加するが、Commands onlyターゲットの場合はリンクコマンドでなくポストビルドステップコマンドを追加する。ただし元々ののポストビルドステップ実行がキャンセルされるわけではないので、結果としてポストビルドステップコマンドを2回実行する。

wxArrayString DirectCommands::GetTargetLinkCommands(ProjectBuildTarget* target, bool force) const
{
...
switch (target->GetTargetType())
{
case ttConsoleOnly:
...
case ttExecutable:
...
...
case ttCommandsOnly:
// add target post-build commands
ret.Clear();
AppendArray(GetPostBuildCommands(target), ret);
return ret;
break;
default:
...
}
...
return ret;
}

ソースコード(ファイル実行)(抜粋)

[Build|Run]などはCompilerGCC::Run(plugins\compilergcc\compilergcc.cpp:1811)でファイル実行する。Commands onlyターゲットの場合は[Project|Set programs' arguments]の[Select target]ダイアログ[Host application]のホストアプリケーションを実行し、これが定義されていない場合はYou must select a host application to "run" a commands-only target...をメッセージボックスに出力する。[Host application]は本来Dynamic libraryターゲット(DLL)デバッグでDLLをアタッチするホストアプリケーションを指定するものでCommands onlyターゲットに対しては用語が不適切である。

int CompilerGCC::Run(ProjectBuildTarget* target)
{
...
wxString hostapStr = platform::windows
? strQUOTE + target->GetHostApplication() + strQUOTE
: EscapeSpaces(target->GetHostApplication());
...
if (target->GetTargetType() == ttConsoleOnly || ...)
{
...
}
if ( target->GetTargetType() == ttDynamicLib
|| target->GetTargetType() == ttStaticLib )
{
...
}
else if (target->GetTargetType() != ttCommandsOnly)
{
...
}
else
{
// commands-only target?
if (target->GetHostApplication().IsEmpty())
{
cbMessageBox(_("You must select a host application to \"run\" a commands-only target..."));
m_pProject->SetCurrentlyCompilingTarget(0);
return -1;
}
command << hostapStr << strSPACE;
command << target->GetExecutionParameters();
...
}
wxString script = command;
...
if (!cmd.Replace(_T("$SCRIPT"), script))
// if they didn't specify $SCRIPT, append:
cmd << command;
...
m_CommandQueue.Add(new CompilerCommand(cmd, wxEmptyString, m_pProject, target, true));
...
return 0;
}