Code::BlocksのPATH改変におけるライブラリディレクトリ追加をソースコードから解析する。
ダウンロードリンク
ソースコード(抜粋)
以下におけるライブラリディレクトリの定義は参照元に従う。
ターゲットビルドオプションのライブラリパス
プロジェクトを開くとCode::Blocksは全ターゲットにCompilerCommandGenerator::GetOrderedLibrariesDirs(sdk\compilercommandgenerator.cpp:767)をコールし、戻り値をターゲットビルドオプションに追加するライブラリパスとして記憶する。
wxArrayString CompilerCommandGenerator::GetOrderedLibrariesDirs(Compiler* compiler, ProjectBuildTarget* target)
{
wxArrayString result;
if (target)
{
wxArrayString prjSearchDirs = target->GetParentProject()->GetLibDirs();
wxArrayString tgtSearchDirs = target->GetLibDirs();
wxArrayString searchDirs;
searchDirs = GetOrderedOptions(target, ortLibDirs, prjSearchDirs, tgtSearchDirs);
...
m_LinkerSearchDirs.insert(m_LinkerSearchDirs.end(), std::make_pair(target, searchDirs));
result = GetOrderedOptions(target, ortLibDirs, target->GetParentProject()->GetLibDirs(), target->GetLibDirs());
}
const wxArrayString& carr = compiler->GetLibDirs();
for (unsigned int x = 0; x < carr.GetCount(); ++x)
result.Add(carr[x]);
...
return result;
}
m_LinkeSearchDirsはターゲットからライブラリディレクトリを連想するマップだが、プロジェクトライブラリディレクトリとターゲットライブラリディレクトリのみを記憶する。関数はその後に戻り値にコンパイラライブラリディレクトリを追加してリターンする。
PATHに自動追加されるライブラリディレクトリ
PATHに自動追加するライブラリディレクトリはCompilerCommandGenerator::GetLinkerSearchDirs(sdk\compilercommandgenerator.cpp:1110)でm_LinkeSearchDirsから取得される。上述のようにm_LinkeSearchDirsはコンパイラライブラリディレクトリを含まない。
const wxArrayString& CompilerCommandGenerator::GetLinkerSearchDirs(ProjectBuildTarget* target)
{
static wxArrayString retIfError;
retIfError.Clear();
SearchDirsMap::iterator it = m_LinkerSearchDirs.find(target);
if (it == m_LinkerSearchDirs.end())
return retIfError;
return it->second;
}
CompilerGCC::DoRunQueue(plugins\compilergcc\compilergcc.cpp:1203)は[Build]メニューコマンドの実行部である。[Build|Run]を実行すると、cbGetDynamicLinkerPathForTarget(sdk\cbproject.cpp:1751)を介しCompilerCommandGenerator::GetLinkerSearchDirsで得られたライブラリディレクトリを一時的に環境変数へ加えて開発プログラムを起動する。CB_LIBRARY_ENVVARマクロはウィンドウズ版ではPATH、ユニックスライク版ではLB_LIBRARY_PATHに置換される。
int CompilerGCC::DoRunQueue()
{
...
CompilerCommand* cmd = m_CommandQueue.Next();
...
wxString oldLibPath;
wxGetEnv(CB_LIBRARY_ENVVAR, &oldLibPath);
...
if (cmd->isRun)
{
...
wxString newLibPath = cbGetDynamicLinkerPathForTarget(m_pProject, cmd->target);
newLibPath = cbMergeLibPaths(oldLibPath, newLibPath);
wxSetEnv(CB_LIBRARY_ENVVAR, newLibPath);
}
...
process.PID = wxExecute(cmd->command, flags, process.pProcess);
...
wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
delete cmd;
return DoRunQueue();
}