Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are changes in source not always reflected in machine code after build while rebuild works?

Tags:

c++

build

qt

Sometimes when I change code in my Qt project (Qt Creator 2.1.0 with mingw32), the changes don't get reflected in the produced machine code after building it. This happens mostly when I change things like default values in constructors or the order of parameters in methods/constructors. Usually, a full rebuild fixes that (but takes a few minutes).

I'm helping myself by deleting the generated executables or librarys before building, which seems to help most of the time. Does that mean that theres something going wrong when linking the object files?

I'm coming from java/.net and I'm used to a different behaviour. I'd be happy if anyone could explain me what I'm doing wrong and/or point me to some related articles.

Thank you!

like image 685
atamanroman Avatar asked Mar 29 '11 09:03

atamanroman


3 Answers

Usually, after a change in a header, all source files including that header should be rebuilt. However, qmake is a bit peculiar in this regard, you need to set DEPENDPATH for include folders other than the current directory. E.g., if you have

INCLUDEPATH += somepath_in_my_project

also add

DEPENDPATH += some_path_in_my_project

Only with DEPENDPATH, files built by the .pro files are rebuilt if some header in some_path_in_my_project changes (if they include that header)!

I suggest to add for each INCLUDEPATH line an identical DEPENDPATH line, unless you include some system directory you don't expect to change.

Edit:

A similar problem exists when linking statically with qmake: If the static lib foo.a changes, binaries linking against it are not relinked. That's a bug in QMake, not generating the correct dependencies.

A workaround I found in a former project:

static:unix:TARGETDEPS += path_to_my/somestaticlib.a
static:win32:TARGETDEPS += path_to_my/somestaticlib.lib

Edit edit:

Since some time (Qt 5?), above code should use POST_TARGETDEPS instead of TARGETDEPS.

like image 128
Frank Osterfeld Avatar answered Nov 09 '22 16:11

Frank Osterfeld


The most common case for that are broken dependencies. In the particular case of default arguments to functions, they are resolved at the place of call, so if you just recompile the function, the code will be exactly the same. You need to recompile the caller. If the dependencies in the project are not correct and the build system does not detect that it needs to recompile the caller, and only recompiles the callee then you will see that effect.

Analyze the dependencies and fix them.

Example:

// what you write                  // what the compiler generates
void foo( int i = 0 ) {}           void foo( int i ) {} // default removed
int main() {                       int main() {
   foo();                             foo( 0 );         // compiler injected
}                                  }
like image 24
David Rodríguez - dribeas Avatar answered Nov 09 '22 17:11

David Rodríguez - dribeas


If you're listing all relevant header files in a project file this shouldn't happen. But actually it happens all the time because QMAKE is buggy (it has known problems with dependencies generation unfixed for years). So better clean it and recompile or use Cmake. And also QMAKE knows nothing (and detect almost nothing) about dependencies between source files and header files and that may lead to problems like that.

like image 3
Serge Dundich Avatar answered Nov 09 '22 18:11

Serge Dundich