I have a simple console project, which have "main.h" and "main.cpp".
main.h is an empty file, select the option "Compile file", and use custom build command: cmd /c copy $file main1.h, select the priority weight to 0.
main.cpp's content:
#include "main1.h"
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
First press build button the log is below:
-------------- Build: Debug in depend (compiler: GNU GCC Compiler)---------------
[ 33.3%] cmd /c copy E:\code\cb\test_code\depend\main.h main1.h
1 file(s) copied.
[ 66.7%] g++.exe -Wall -fexceptions -g -c E:\code\cb\test_code\depend\main.cpp -o obj\Debug\main.o
[100.0%] g++.exe -o bin\Debug\depend.exe obj\Debug\main.o
Output file is bin\Debug\depend.exe with size 52.54 KB
Process terminated with status 0 (0 minute(s), 1 second(s))
0 error(s), 0 warning(s) (0 minute(s), 1 second(s))
Now, press build again, I have the custom build command run again, then link again.
-------------- Build: Debug in depend (compiler: GNU GCC Compiler)---------------
[ 50.0%] cmd /c copy E:\code\cb\test_code\depend\main.h main1.h
1 file(s) copied.
[100.0%] g++.exe -o bin\Debug\depend.exe obj\Debug\main.o
Output file is bin\Debug\depend.exe with size 52.54 KB
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
press build again, I get the same result as before, so my questions are:
1, I don't change main.h, why the custom command run again?
2, why the linker run again and again?
3, if the dependency checker know main1.h changed, why not compile main.cpp?
Debugged a little, I found the build command was generated in the below code:
wxArrayString DirectCommands::GetTargetCompileCommands(ProjectBuildTarget* target, bool force) const
{
wxArrayString ret;
// set list of #include directories
DepsSearchStart(target);
// iterate all files of the project/target and add them to the build process
size_t counter = ret.GetCount();
MyFilesArray files = GetProjectFilesSortedByWeight(target, true, false);
size_t fcount = files.GetCount();
bool hasWeight = false;
unsigned short int lastWeight = 0;
for (unsigned int i = 0; i < fcount; ++i)
{
ProjectFile* pf = files[i];
// auto-generated files are handled automatically in GetCompileFileCommand()
if (pf->AutoGeneratedBy())
continue;
const pfDetails& pfd = pf->GetFileDetails(target);
wxString err;
if (force || IsObjectOutdated(target, pfd, &err))
{
// Add a wait command if the weight of the current file is different from the previous one
// Because GetCompileFileCommand() already adds a wait command if it compiled a PCH we
// check the last command to prevent two consecutive wait commands
if (hasWeight && lastWeight != pf->weight && (ret.IsEmpty() || ret.Last() != COMPILER_WAIT))
ret.Add(wxString(COMPILER_WAIT));
// compile file
wxArrayString filecmd = GetCompileFileCommand(target, pf);
AppendArray(filecmd, ret);
// Update the weight
if (!hasWeight)
hasWeight = true;
lastWeight = pf->weight;
}
else
{
if (!err.IsEmpty())
ret.Add(wxString(COMPILER_WARNING_LOG) + err);
}
if (m_doYield)
Manager::Yield();
}
// add link command
wxArrayString link = GetLinkCommands(target, ret.GetCount() != counter);
AppendArray(link, ret);
return ret;
}
First, it looks like when checking for the status of "main.h", the function "IsObjectOutdated" always return true, so bad, this means why the custom command was always added, this result the command:
[ 50.0%] cmd /c copy E:\code\cb\test_code\depend\main.h main1.h
1 file(s) copied.
Second, look at the code: "ret.GetCount() != counter", so the linker command is added then, this result the command:
[100.0%] g++.exe -o bin\Debug\depend.exe obj\Debug\main.o
Third, do you think it is better to write "ret.GetCount()>0", the counter variable is always 0, but I think here we use 0 is much better, any ideas? ("size_t counter = ret.GetCount();" is the only place to set the counter value, which is after "wxArrayString ret;")