パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
ソースコード(Code::Blocksのライブラリディレクトリ追加)

Code::BlocksのPATH改変におけるライブラリディレクトリ追加をソースコードから解析する。

ダウンロードリンク

ソースコード(抜粋)

以下におけるライブラリディレクトリの定義は参照元に従う。

ターゲットビルドオプションのライブラリパス

プロジェクトを開くとCode::Blocksは全ターゲットにCompilerCommandGenerator::GetOrderedLibrariesDirs(sdk\compilercommandgenerator.cpp:767)をコールし、戻り値をターゲットビルドオプションに追加するライブラリパスとして記憶する。

wxArrayString CompilerCommandGenerator::GetOrderedLibrariesDirs(Compiler* compiler, ProjectBuildTarget* target)
{
wxArrayString result;
if (target)
{
// currently, we ignore compiler search dirs (despite the var's name)
// we only care about project/target search dirs
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));
// decide order
result = GetOrderedOptions(target, ortLibDirs, target->GetParentProject()->GetLibDirs(), target->GetLibDirs());
}
// compiler dirs
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; // keep old PATH/LD_LIBRARY_PATH contents
wxGetEnv(CB_LIBRARY_ENVVAR, &oldLibPath);
...
if (cmd->isRun)
{
...
// setup dynamic linker path
wxString newLibPath = cbGetDynamicLinkerPathForTarget(m_pProject, cmd->target);
newLibPath = cbMergeLibPaths(oldLibPath, newLibPath);
wxSetEnv(CB_LIBRARY_ENVVAR, newLibPath);
}
...
process.PID = wxExecute(cmd->command, flags, process.pProcess);
...
// restore dynamic linker path
wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
delete cmd;
return DoRunQueue();
}