What exactly is compiled in precompiled headers? - precompiled-headers

From what I know, headers used properly should only contain function prototypes and defines, which are not compiled. Only the global variables will be compiled. So why bothering with precompiled headers when there's almost nothing to compile ? Am I missing something ?

The point of precompiled headers is to speed up compilation.
And yes, everything is compiled, even if it does not generate
assembly output, it still generates internal compiler symbols.

Related

Mysterious Qt undefined interface : investigation

I am writing a typical Qt (4.8.2) app with plugins. One of the plugins includes a couple custom interfaces, by calling the Q_INTERFACE macro. Those interfaces are found in .h files visible to the project (via the .pro includes) and they all contain a macro call to Q_DECLARE_INTERFACES.
Yet upon compiling the moc file I get an undefined interface error in the main .h file of the plugin. It doesn't tell me which though, it only specifies the line of the first (I tried changing the order but it makes no difference - unless all interfaces are affected - heck, who knows, that could be the case.)
This plugin works at other people's desks. Some of the stuff in the main app is written with Qt 5 but always with macros to check for the version and include other code for earlier versions like mine. This also works at other people's desks who work with 4.8.2 for their plugins.
Where to look for the cause of that error ?
I don't know why my question got voted down, but here's the answer :
With the copy of the project I also received the moc_*.cpp files and some files called mocinclude.tmp . This was a first git add mistake.
But there is another problem : at least the latter (if not the former) does not get cleaned properly or recreated by Qmake/make clean.
A third problem : In mocinclude.tmp there were absolute file paths from the computer where the project was first created, which wasn't mine. Relative paths would have been less error-prone.
Those wrong absolute paths led to the "undefined interface" error (which is nothing less but a "file not found" error in the case of a needed interface file) when compiling the moc files.
Deleting all mocinclude.tmp (and moc files) solved my problem.
(I also made sure to tell git to not track them anymore.)

Difference between the qtquickcompiler and the new JIT .qmlc cache?

I'm a little bit confused about the qtquickcompiler, the JIT qml caching and what is available (and what is not) in the open source version of qt 5.8 (respectively 5.9).
Basically, I want to protect my .qml and .js files from being readable in my release build. I started a new example QtQuick project without editing any code. I followed these instructions and added the CONFIG += qtquickcompiler in the .pro file, but it has no effect.
My .qml files are built into the .exe (on Windows), but if look in the executable, e.g. with notepad++, I can still see the source code of the .qml files.
On the other hand, if I don't use the QRC for my .qml files, .qmlc files are created for every of my .qml at runtime. These files are not (easily?) readable. But I don't find a way to use only the .qmlc files without shipping the .qml files in my build (and I don't think it was meant to be like that).
Coming to my question: Is there a way to protect my .qml and .js files with the open source version of qt? And what is the difference between the qtquickcompiler and the new JIT .qmlc?
Updated answer:
Since Qt 5.11, the qt quick compiler is also available in the open source version:
CONFIG += qtquickcompiler
See https://wiki.qt.io/New_Features_in_Qt_5.11
No, it was going to be, but then they gave up on those plans for the time being and replaced it with the caching thing.
I don't think you will be able to reuse .qmlc files on another computer, as IIRC they are not architecture portable.
In the future, it should be possible to pre-compile .qml to .qmlc ahead of time and bundle those into the application binary.
If your files are on the file system, then there is no way to protect them, from being read, reverse engineered, or tampered with.
With the compiler, the QML code is translated to C++ code, which is then compiled to a native binary. Also, last time I checked, if you go for the compiler, it is an "either / or" situation, if you use compiled qml you can only use compiled qml, so no mixing with regular qml files. It is also ahead of time, and requires a commercial license.
The qml caching in contrast is just-in-time (possibly ahead of time in the future), doesn't require a commercial license and doesn't come with the limitation that prevents you from using regular qml files. I am not aware of the implementation details, but it certainly is not qml code translated to C++ and then compiled, as it happens on the client side and doesn't require having Qt or even a C++ compiler installed. It doesn't really sound like bytecode either, as IIRC it is not binary compatible between platforms, it is more like caching the qml file processing result to avoid on doing it every time.
As outlined in this answer, with some extra work it might be possible to implement a decent amount of protection, for example encrypted QML files or binary resources, but I still haven't dug into it.
Lastly, if you set compression for the qrc file with a low threshold, it will somewhat obfuscate the QML code in the executable binary, but even so, it is regular zip compression, so if your code is really worth stealing, it will not really prevent that, just make it a tad less trivial.
Is there a way to protect my .qml and .js files with the open source version of qt?
Not yet. Up to (and including) 5.8 you'll need to buy a license in order to use the QML compiler.
And what is the difference between the qtquickcompiler and the new JIT .qmlc?
That the compiler will turn QML into C++, which gets then compiled into your application. The .qmlc files are a cache generated by the engine to avoid parsing / optimizing / etc. the same files all over again. Yet, they're a cache -- you'll need to original source around in case they don't get used. At the Qt Contributors' Summit 2016 there have been some discussions about how to streamline and integrate the compiler with the cache, but so far nothing exists.
Coming to my question: Is there a way to protect my .qml and .js files
with the open source version of qt?
Yes, of course,
look at my answer:
https://stackoverflow.com/a/40861056
You can use an encripted resource file, an decrypt it in execution time...
I do that in all my projects ...
Is not a trivial job, but works fine.

QML error says that svg is unsupported

I've used plugins before, but after I recompiled my qt libraries, I haven't been able to successfully use .svg image files any longer. There error I get is as follows:
file:///C:/Users/RBhatia/Documents/SettingsMenu/SettingsMenu/SlicingComp.qml:41:5: QML Image:
Error decoding:
file:///C:/Users/RBhatia/Documents/SettingsMenu/SettingsMenu/img/sliceStep_slice1.svg: Unsupported image format
I have checked all my .dll files to make sure they are in 64 bit format. I also checked my environment variables, and even tried to use different librariesm but I simply cannot figure out what changed to cause this issue.
The problem is not missing header files. It's due to missing dependencies to Qt libraries as mentioned in that comment here: Comment by JamesL
To use SVG images you need to specify QtSvg, QtXml, QtGui, and QtCore to be deployed with your project.
The most probable reason I can think of is that you were missing some svg header files when you compiled your qt. If you do not add -svg to your configure, svg is treated as optional. Means if everything is there to build the svg plugin, it is build, else this feature is silently dropped.
You said, you checked your .dll files. Did you also check the plugins folder? Something like $QTDIR/plugins/imageformats. Must contains a qsvg4.dll. Or qsvg5.dll for Qt5.

XCode compiles entire project each time I run

On a new project I have started, XCode has decided that it will compile every file in the project every time I run it, rather than just compiling files that change (and files dependent on those). As there are getting to be more and more files in the project, this becomes a bigger and bigger burden in both time and battery life.
It is possible that I have changed a setting somewhere that affected this; or, maybe not. What are some project settings that I should be looking at?
If Xcode recompiles most or all of your source files whenever you do a build, that usually means that those files are all directly or indirectly dependent on some header file that has changed. Here are some things to look for:
Do your source files tend to #import some top-level header file that itself recursively imports a bunch of lower-level header files? If any file in that tree of dependent headers is modified, it will force recompilation of any .m file that imports the top-level header file. You may be able to reduce these dependencies by importing headers for lower level submodules, or better yet, for just the specific headers you need for each file. (Note: Some libraries that aren't designed to be used this way can make this approach challenging or impossible in some cases.)
Some third party development tools and static libraries run scripts that generate or modify code as part of their build process. If your source files are dependent on a header file that's generated by a script, they'll be recompiled every time the script regenerates that header file. Even if the code generated by the script doesn't change, dependent source files will be recompiled if the last-modified date of the header file changes. It may take some clever hacking to eliminate redundant compilation if this is your issue.
Don't forget to check your precompiled header (.pch) file to see what's being imported there. The contents of that file are effectively injected at the top of every .m file in your project at compile time.
Try to minimize dependencies by moving as many #import statements as possible out of your .h files and into your .m files. You can generally get away with just importing the headers for your class's superclass and any protocols your class implements in its .h file. You can use forward declarations instead of #import statements for any other classes, data types, or protocols you use in your class's #interface.
I realize this question is over a month old, but I had a similar problem in moving an old project to Xcode 4. After much hair-rending, I discovered that Xcode 4 (4.2 in my case) has a bug where, if there are any non-ASCII characters in the full path either of a source file, or in the full path of any headers the source file includes, it will be recompiled every time you build. This includes the prefix header, in which case a full compile will be triggered every time. In my case, the previous programmer had appended 'ƒ' to several folder names, and once I removed those, it worked perfectly.
Anyway, I stumbled upon this question during my (unsuccessful) attempts to Google an answer and thought I'd share my solution.

Show all compile errors in FlexBuilder?

Is it possible to make FlexBuilder show all compile errors in all files? FlexBuilder does not show errors in Action Script files, that are not referenced. Also very often I fix a problem just to see new problems pop up after compiling the whole project although these errors existed long before.
IntelliJ is showing all compile errors it can find and I would like to have FlexBuilder behaving the same way since IntelliJ is not mature enough to handle our complex set up. Is there a compiler switch to enable this?
The compiler can (and will) show errors only in code that you tell it to compile, and like you said, whatever is not referenced in the code you compile, will not be compiled, and thus, checked by the compiler.
So if you want to have the compiler check some part of your code, you need to tell it to compile it. I'm not sure how your projects are set up, but I'm assuming that you're compiling a bunch of smaller projects that are all using different parts of a shared codebase (or something similar.) In this case, you could either:
set up some sort of "master" project that references all of your code, compiling which would then check for errors everywhere (maybe you have this already, in which case the solution is simply to compile this regularly)
set up a job/target for compiling the AsDoc documentation for all of your code -- you could then run this regularly and at the same time you'd be keeping your API docs up to date
The following MXMLC compiler arguments might be useful:
-includes className [...]
Links one or more classes into the output SWF, regardless of whether they are required at compile time.
-include-libraries swcPath [...]
Links the entire contents of one or more SWC libraries into the output SWF, regardless of whether its classes are required at compile time.

Resources