09-30-2013 12:33 PM
I've just noticed another strange behaviour of CVI 2013, and it's related with precompiled headers (am I the only user of this feature?).
It's very simple to trigger:
Then the build will terminate with this error messages:
... main.c - 2 errors, 2 warnings 1, 1 error: definition of the macro '_TARGET_FILE_VERSION_' conflicts with the definition used to build the precompiled header 1, 1 <built-in>:162:1: note: definition of macro '_TARGET_FILE_VERSION_' in the precompiled header 1, 1 error: definition of the macro '_TARGET_PRODUCT_VERSION_' conflicts with the definition used to build the precompiled header 1, 1 <built-in>:163:1: note: definition of macro '_TARGET_PRODUCT_VERSION_' in the precompiled header Build failed.
As additional information please note that there is no reference to _TARGET_PRODUCT_VERSION_ and _TARGET_FILE_VERSION_ macros.
The reason is obvious: the precompiled header retains the old values of these variables.
I don't have found any workaround but to stop using the auto-increment feature.
10-01-2013 02:11 AM
Hello carlox,
I have opened report #429548 to track this issue. We will investigate and fix it in a future version.
I think I can suggest a possible workaround other than to stop using the auto-increment feature: doing a rebuild of the project instead of a build after you modify a source file that does not trigger precompiled header recompilation.
Best regards,
Nelu F. || National Instruments.
10-01-2013 04:31 AM
Thanks NeluF.
As a further detail, it's possible to create a scenario that gives the same problem in debug mode, going back from release configuration. I observed it yesterday just after writing my post.
I'm not going on this issue because I'm short on my project schedule.
A full rebuild can be a workaround, sure, but when you have a project with 80+ source files recompiling all files is not exactly instaneous, you know.
10-03-2013 06:41 AM
Hi Carlo,
We have investigated the issue. The cause of the build error is that the precompiled header is not rebuilt, but the source file is, so only the source file is compiled with the new values of the version macros. Note that even the compilation of the source file is triggered not by the version change, but only by any edits made to it.
Even though the _TARGET_PRODUCT_VERSION_ or _TARGET_FILE_VERSION_ macros are not actually used in your code, the build process cannot know that, so it has to pass them as compiler defines to all files, including the precompiled header. The root cause of the build error is that the build process is not correctly detecting that these macros have changed.
Please note that when we correct our build process to detect this change, CVI will have to actually rebuild the entire project behind the scenes with each build that increments the version, because any of the files, including the precompiled headers themselves, could be using the version macros. Otherwise, you could end up with inconsistencies among any source files that happen to use these macros. Also note that regenerating just the precompiled header (which you could do even now by deleting the .pch file from the build folder of the configuration) would still trigger a full rebuild because the date of the .pch file becomes newer and because it is automatically included by all source files.
It turns out that even earlier versions of CVI had similar problems with the version changes, although it did not result in build errors. The resulting output binary would not use the up-to-date values of the version macros in the code.
For example, the code snippet:
printf("FileVer: %s\n", _TARGET_FILE_VERSION_); printf("ProdVer: %s\n", _TARGET_PRODUCT_VERSION_);
would not be returning the correct/latest versions after consecutive builds, since the files themselves were not automatically recompiled
I realize that, as you mentioned, the build error is reproducible in debug configuration as well, but the need to rebuild the entire project does not apply to debug configurations. For it to apply, you would have to manually change the version numbers, since auto-increment has effect only in release configurations.
Note that CVI already does a rebuild when one of the Compiler Defines changes. Effectively, these version macros aren't any different than the Compiler Defines macros.
Furthermore, with CVI 2013 you can take advantage of the new multi-core compilation feature to help reduce your build times for larger projects (Options > Build Options > Build Process Options tab > Number of concurrent compiles) so that might mitigate somewhat the downside of a full rebuild.
Given all these, the performance hit from a behind-the-scenes rebuild should affect only your release builds, and only if you have version auto-increment enabled. Since development is typically done using the Debug configuration and Release builds are normally not all that frequent, does this solution look acceptable to you?
Best regards,
Alpar
10-03-2013 01:37 PM
Alpar, it's clear that current implementation of _TARGET_PRODUCT_VERSION_ and _TARGET_FILE_VERSION_ is incompatible with the auto-increment feature.
The full rebuild "behind the scenes" would work, but it's an ugly patch, in my opinion: it would bring to a perfect equivalence between "build" and "rebuild" commands when the auto-increment is used.
I think that the only elegant way to solve this problem is to trigger the auto increment only when a rebuild command is issued. The normal build will use the current values.
It must only clearly documented, of course.
10-04-2013 06:45 AM
Hello Carlo,
I don't agree that the "behind the scenes" rebuild is an ugly patch. This is no different than what happens if you change some setting in the Build Options dialog, as Alpar mentioned earlier. Because most of those build options are inputs to the build, on the next build CVI will have to recompile every file in your project whenever one of those inputs changes. All ADEs do the same thing during their dependency checks.
We cannot establish a different versioning policy for builds and rebuilds. The only difference between a build and a rebuild is that a build checks first what really needs to be built and builds only what it needs, whereas a rebuild always builds everything. It's not okay to end up with a different version in your exe or dll if you happen to do a build instead a rebuild.
You say that this policy sets up a perfect equivalence between builds and rebuilds when auto-increment is used. That is true, but only for release configurations. In my opinion this isn't that bad unless you're doing most of your code development using release configurations. Is that what you're doing?
Luis
10-04-2013 01:16 PM
Luis, I hope that my words didn't sound offensive: it wasn't my intention.
No, I don't do the bulk of my development in release configuration.
In my applications, I usually have some "release only" and "debug only" code, selected by conditional compilation by using the NDEBUG / _CVI_DEBUG_ predefined constants.
Sometimes, by chance, it happens I had to do a quick fix in the "release only" code. It isn't a frequent event, anyway.
When this happened on CVI 2013, the compilation ended in a fatal error, on perfectly valid code.
The whole scenario is not exactly common, but it could be misleading to other users, too.
I think I can survive doing only full rebuilds in release configuration: its impact can be made negligible by using a more conventional development pattern.
IMHO all the problems come from the definition itself of the two constants.
Both of them refer to the version of something that should not exist at compilation time, something that in a logical sequence should come to life only when the executable file is generated, or - more precisely - when resource compiler appends to the executable the version information.
Preprocessor constant must obviously be known in the first phase of compilation, so the compiler is somewhat betting on the build result, hoping that all steps involved in executable generation will be successful.
Given this, these constant should not exist at all.
If someone needs to know at run time the actual executable version number, it's not hard get it by using GetFileVersionInfo() API from version.dll. I don't know if there is some equivalent on Linux.
And if someone claims he/she needs to know at compilation time the version number, then he/she is simply doing it wrong...
A sort of compromise could be to exclude from the constants any... variable part, e.g. the autoincrementing numbers. After all, a proper costant must be constant, isn't it ?
I'm very interested to hear your opinion.
10-05-2013 03:37 AM
@carlox wrote:
A sort of compromise could be to exclude from the constants any... variable part, e.g. the autoincrementing numbers. After all, a proper costant must be constant, isn't it ?
This is already the case:
_TARGET_FILE_VERSION_ | Windows Linux | Defined as the value in the File Version option of the Version Info dialog box. | This macro does not include increment symbols; for example, if the version string in the Version Info dialog box is 1.0.0.0+, this macro is defined to 1.0.0.0.
|
||
_TARGET_PRODUCT_VERSION_ | Windows Linux | Defined as the value in the Product Version option of the Version Info dialog box. | This macro does not include increment symbols; for example, if the version string in the Version Info dialog box is 1.0.0.0+, this macro is defined to 1.0.0.0.
|
10-05-2013 03:50 AM - edited 10-05-2013 03:51 AM
No, Wolfgang, you have misinterpreted the doc.
What is not included in the predefined constant is only the "increment symbol", that is the "+" character.
The value of constant includes all four numeric fields, including the incrementing ones.
10-05-2013 04:01 AM
Touché! You're right, the doc refers to the symbol But at least the debug version is not autoincremented...