Reputation: 435
I had a program written using Qt's shared library version (5.2.0) and it displayed fonts okay (presumably filling it's Database from /usr/share/fonts). (Not sure whether the Designer text is from the same Database as the programmed font handling.) But then I recompiled it under the open source static version (5.2.0), and the fonts went ugly.
I disrupted the path to the installed Qt (since the whole idea of the static version is to be independent of development directories) and sure enough it complained of not being able to access any fonts. So I concluded Qt changed their static version to no longer input /usr/share/fonts. A little research on the internet told me they instead look under ...somedir/lib/fonts.
With a little more research I found I could use env var QT_QPA_FONTDIR to set the directory of search (though I suspect it might have been reduced to a one-level search, not recursive). Not wanting to have to write a script to wrap the program and set the environment variable before calling it, I proceeded to use a putenv() in the program. I chose a place that I thought would set the variable before Qt read the environment, and since global contructors are called before main() and certainly before QApplication is instantiated, I put it in a constructor.
But, guess what, they seem to read the environment before my constructor set the QT_QPA_FONTDIR=/usr/share/fonts.
So please help!!!! How do I make MY constructor get executed first?
Upvotes: 0
Views: 199
Reputation: 435
Thank you Aiken Drum. The link order worked. I created the smallest .cpp that made a constructor to be instantiated globally calling the putenv() to set up my environment. I put it first in the .pro file, and checked that the makefile it created had it first in the link line. And, hey presto!! the Qt program now gets the font Database from the right place. Thank you so much. It's the link order that sets the constructor order (at least with GCC).
Upvotes: 0
Reputation: 593
Some compilers offer pragmas that attempt to help you do such things, but the simple truth is that C++ offers no guarantees of the order of global construction between modules. There isn't even a guarantee that one object dependent on another in another module will be initialized second. Globals are a minefield in this respect.
If you need a portable solution, there really isn't one.
If you can guarantee your compiler will always be the same flavor, then you can use hacks like pragmas, attributes, or link order to work around the problem. For instance, gcc offers a variable attribute called init_priority, though I'm not sure you can make your priority higher than the default.
Really, it would be better to solve the problem another way.
Upvotes: 2