User forums > General (but related to Code::Blocks)
Object output dir cannot reflect global variable change
(1/1)
KodamaDeveloped:
CB20.03, Win10/mingw64.
Do the followings steps.
* [Settings|Global variables] to open [Global Variable Editor] dialog. For the currently selected set add a new variable named "testdir" by [Current variable|New]. For the variable define its [Build-in fields|base] as "XXX". Hit [Close].
* [File|New|Project] to open [New from template] dialog. Select [Console application] and hit [Go] to run the console application wizard. By the wizard create a new project of which name is "ObjDirTest".
* [Project|Properties] to open [Project/targets options] dialog and select [Build targets] page. For the currently selected target set [Output filename] as "bin\$(#testdir)\ObjDirTest.exe" and [Objects output dir] as "obj\$(#testdir)\". Hit [OK].
* [Build|Rebuild] to build the project and see [Logs & others] window [Build log] page to check the excuted commands.
--- Code: ---g++.exe -Wall -fexceptions -g -c D:\Users\Takeshi\MinGW\CB_Work\ObjDirTest\main.cpp -o obj\XXX\main.o
g++.exe -o bin\XXX\ObjDirTest.exe obj\XXX\main.o
--- End code ---
Normally all "$(#testdir)"s have been replaced with "XXX"s. Continue with the following steps.
* [Settings|Global variables] to open [Global Variable Editor] dialog. Select "testdir" in [Current variable] and change its [Built-in fields|base] as "YYY". Hit [Close].
* [Build|Rebuild].
--- Code: ---g++.exe -Wall -fexceptions -g -c D:\Users\Takeshi\MinGW\CB_Work\ObjDirTest\main.cpp -o obj\XXX\main.o
g++.exe -o bin\YYY\ObjDirTest.exe obj\XXX\main.o
--- End code ---
Oddly only "$(#testdir)" in the execution output filename has changed to "YYY" but that in the objects output remains "XXX". Continue with the following steps.
* [File|Close project] to close the project.
* [File|Recent projects|...\ObjDirTest\ObjDirTest.cbp] to reopen the project.
* [Build|Rebuild].
--- Code: ---g++.exe -Wall -fexceptions -g -c D:\Users\Takeshi\MinGW\CB_Work\ObjDirTest\main.cpp -o obj\YYY\main.o
g++.exe -o bin\YYY\ObjDirTest.exe obj\YYY\main.o
--- End code ---
Eventually all "$(#testdir)"s have been replaced with "YYY"s.
Not only global variables show the sympton but environment variables and custom variables. MacrosManager::ReplaceMacros() replaces such variables. The function is called so many times from everywhere that it's hard to make complete analysis. The following is my wild guess.
Almost all variables are replaced just before a build is executed, except for those regarding object files including their output directories. Those are stored in pfDetails class instances after the variable replacements. A project file calls ProjectFile::GetFileDetails() to get a pfDetails instance for a specific target. The function creates the instance if it does not exist, otherwise returns previously created one. Because a build gets the pfDetails instance by the function, the first build uses a new instance and the following builds uses the same instance without any change. Therefore the following builds never changes the output directory.
[sdk\projectfile.cpp:275]
--- Code: ---// map target to pfDetails
void ProjectFile::UpdateFileDetails(ProjectBuildTarget* target)
{
if (!project)
return;
if (!compile && !link)
return;
// update PCH output name (in case project PCH mode was changed)
if (FileTypeOf(relativeFilename) == ftHeader)
SetObjName(relativeToCommonTopLevelPath);
if (!target) // update all targets
{
int tcount = project->GetBuildTargetsCount();
for (int x = 0; x < tcount; ++x)
{
ProjectBuildTarget* bt = project->GetBuildTarget(x);
DoUpdateFileDetails(bt);
}
}
else
DoUpdateFileDetails(target);
}
void ProjectFile::DoUpdateFileDetails(ProjectBuildTarget* target)
{
// if we don't belong in this target, abort
if (!target || buildTargets.Index(target->GetTitle()) == wxNOT_FOUND)
return;
// delete old PFD
pfDetails* pfd = m_PFDMap[target];
if (pfd)
pfd->Update(target, this);
else
{
pfd = new pfDetails(target, this);
m_PFDMap[target] = pfd;
}
}
const pfDetails& ProjectFile::GetFileDetails(ProjectBuildTarget* target)
{
pfDetails* pfd = m_PFDMap[target];
if (!pfd)
{
DoUpdateFileDetails(target);
pfd = m_PFDMap[target];
}
return *pfd;
}
--- End code ---
Actually ProjectFile::UpdateFileDetails() could be used for updating the pfDetails instance, that looks never used for such the purpose.
Is my guess right? Is this already known? Is this a defect or intentional? Thank you.
stahta01:
I have had related but different problems on Windows.
The Linux users seem to never have this type of problem; so, it might be caused by a difference in OS handling of something.
Tim S.
KodamaDeveloped:
Thank you for your comment.
I believe the problem I show is not Windows specific because the place causes problem looks being in the generic codes, which relates ProjectFile::GetFileDetails(). Of course I can't make it sure without the Linux test run, unfortunately I don't have such an environment.
Navigation
[0] Message Index
Go to full version