Building a standalone executable (Windows)
-
wrote on 13 Aug 2019, 20:25 last edited by
Hi all -
I'm returning to this subject; a few months ago, I managed to work out the kinks in building a static version of Qt on Windows. For the interested
I did this as a precursor to being able to build completely self-contained executables. To this end, I think I'm fairly close. I'm using a third-party library, though, that is causing me difficulty.
The library exists in .lib and .dll files. Someone suggested that the .lib actually uses the .dll, and this seems likely given the respective file sizes:
How do I configure my build to absorb these files, so I can distribute a single .exe file?Thanks...
-
Hi.
You can't absorb .dlls files. You need to rebuild your dependencies such as they are all static libraries.
-
wrote on 13 Aug 2019, 20:43 last edited by
So, are you saying that I'd have to rebuild the expat library?
-
Hi
Yes, you have to make your own static version of expat and link that in.
That lib files you have there looks like a import lib and not a static version. -
wrote on 13 Aug 2019, 20:59 last edited by mzimmers
Building expat was easy. There was even a static build in the .sln file.
The resulting file is called libexpatMT.lib. I put this in my .pro file:
INCLUDEPATH += "C:/Users/mzimmers/Desktop/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/lib" LIBS += libexpatMT.lib
And I'm getting a build error:
:-1: error: cannot find -lexpatMT.lib
Is this due to some confusion between Linux and Windows syntax for specifying a library?
EDIT:
I got rid of this error by supplying an absolute pathname for the library:INCLUDEPATH += "C:/Users/MZimmers/apps_desktop/libs" win32:LIBS += "C:/Users/MZimmers/apps_desktop/Qt_apps/wb_utility/libexpatMT.lib"
Now, however, I'm getting several instances of this error:
C:\Users\MZimmers\apps_desktop\Qt_apps\wb_utility\win32\tmp\Release_static\xmlparse.obj):-1: error: undefined reference to `@__security_check_cookie@4'
Any ideas on what I did to incur this?
-
You link the same way to static files:
-LC:/path/to/static/lib -lname_of_lib
Does that library have any dependency ?
-
You link the same way to static files:
-LC:/path/to/static/lib -lname_of_lib
Does that library have any dependency ?
wrote on 13 Aug 2019, 21:35 last edited by mzimmers@sgaist yes, but they all appear to be header files (at least, according to VS). It seems odd that the static build of the expat library would succeed, but that such an error would surface when trying to build my app.
EDIT:
BTW, the doc is a little confusing:
https://doc.qt.io/qt-5/qmake-variable-reference.html#libs
The textual explanation acknowledges what you say about pathnames, but the examples sort of suggest otherwise.EDIT again:
I just had an idea that this is related to some 32-bit/64-bit incompatibility. When I built my static version, I made it 32-bit, because I was trying to use the pre-built expat libraries. I think I now have to create a 64-bit static library. Stand by...
-
wrote on 15 Aug 2019, 15:18 last edited by
I now have a Qt static library (man that takes a long time to build), as well as a static Expat library, included in my project file like so:
LIBS += "C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib"
(I changed the default name of the expat library to eliminate some spurious but annoying VS warnings.)
When I attempt to build, I get errors indicating that the build isn't "seeing" the library (or at least not its contents):
So, what might I be doing wrong? I'm almost positive the "undefined" functions are indeed in the library. Thanks...
-
wrote on 15 Aug 2019, 15:25 last edited by mranger90
@mzimmers said in Building a standalone executable (Windows):
try:
LIBS += -l"C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib"
That's a lower-case ell in front of the library path/name
-
@mzimmers said in Building a standalone executable (Windows):
try:
LIBS += -l"C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib"
That's a lower-case ell in front of the library path/name
wrote on 15 Aug 2019, 15:31 last edited by@mranger90 yeah, I already tried that...despite what the QMake page says, Qt doesn't seem to like the Linux format of specifying libraries:
:-1: error: cannot find -lC:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib
Trying this, though, wasn't without value, as it indicates that I am indeed including the library in my build.
I wonder if this is some weird problem with name decoration...?
-
@mranger90 yeah, I already tried that...despite what the QMake page says, Qt doesn't seem to like the Linux format of specifying libraries:
:-1: error: cannot find -lC:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib
Trying this, though, wasn't without value, as it indicates that I am indeed including the library in my build.
I wonder if this is some weird problem with name decoration...?
-
wrote on 15 Aug 2019, 17:27 last edited by mranger90
Did you try:
LIBS += -L"C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release" -l expat_static
to split the search path and library name into separate directives ?
-
wrote on 15 Aug 2019, 18:35 last edited by
@jonb according to the docs, it should work (at least that's how I interpret it), but it sure doesn't seem to.
mranger: I think using the "normal" win32 format is working for me; I used it with my former version of Expat. I believe the problem lies elsewhere -- perhaps I didn't build the library correctly, though it is distributed as a near-turnkey VS solution.
-
@jonb according to the docs, it should work (at least that's how I interpret it), but it sure doesn't seem to.
mranger: I think using the "normal" win32 format is working for me; I used it with my former version of Expat. I believe the problem lies elsewhere -- perhaps I didn't build the library correctly, though it is distributed as a near-turnkey VS solution.
wrote on 15 Aug 2019, 18:44 last edited by JonB@mzimmers
That docs page is the one I looked at. The examples forwin32:LIBS
do not have the leading-l
. The error messagecannot find -lC:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib
shows it is looking for a filepath
-lC...
. Just a guess. -
@mzimmers
That docs page is the one I looked at. The examples forwin32:LIBS
do not have the leading-l
. The error messagecannot find -lC:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib
shows it is looking for a filepath
-lC...
. Just a guess.wrote on 15 Aug 2019, 18:55 last edited by@jonb the examples don't use the -L/-l, but the text suggests (to me, anyway) that they should work:
If you use the Unix -l (library) and -L (library path) flags, qmake handles the libraries correctly on Windows (that is, passes the full path of the library to the linker).
Anyway, it doesn't really matter, because I'm using this, and it works:
LIBS += "C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib"
At least it worked with the pre-built version 2.2.5; I still don't know what's going wrong here.
-
@jonb the examples don't use the -L/-l, but the text suggests (to me, anyway) that they should work:
If you use the Unix -l (library) and -L (library path) flags, qmake handles the libraries correctly on Windows (that is, passes the full path of the library to the linker).
Anyway, it doesn't really matter, because I'm using this, and it works:
LIBS += "C:/Users/MZimmers/apps_desktop/libs/libexpat-R_2_2_7/libexpat-R_2_2_7/expat/win32/bin/Release/expat_static.lib"
At least it worked with the pre-built version 2.2.5; I still don't know what's going wrong here.
wrote on 15 Aug 2019, 19:16 last edited by JonBIf you use the Unix -l (library) and -L (library path) flags, qmake handles the libraries correctly on Windows (that is, passes the full path of the library to the linker).
You're right, I missed that. Note it also says:
The library must exist for qmake to find the directory where a -l lib is located.
which sounds like just what that error message is indicating is happening (i.e. failing to find the library)?
I did say I was jumping in! What you have on your
LIBS +=
line looks to me as though it should work. -
If you use the Unix -l (library) and -L (library path) flags, qmake handles the libraries correctly on Windows (that is, passes the full path of the library to the linker).
You're right, I missed that. Note it also says:
The library must exist for qmake to find the directory where a -l lib is located.
which sounds like just what that error message is indicating is happening (i.e. failing to find the library)?
I did say I was jumping in! What you have on your
LIBS +=
line looks to me as though it should work. -
wrote on 15 Aug 2019, 22:09 last edited by
Well, this continues to get more interesting: I edited my project file, right-clicked and started the Add Library wizard. When I was finished, I had some stuff added that looked like this:
win32: LIBS += -L$$PWD/../../libs/libexpat-R_2_2_7/expat/win32/bin/Release/ -llibexpatMT INCLUDEPATH += $$PWD/../../libs/libexpat-R_2_2_7/expat/win32/bin/Release DEPENDPATH += $$PWD/../../libs/libexpat-R_2_2_7/expat/win32/bin/Release win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../libs/libexpat-R_2_2_7/expat/win32/bin/Release/libexpatMT.lib else:win32-g++: PRE_TARGETDEPS += $$PWD/../../libs/libexpat-R_2_2_7/expat/win32/bin/Release/liblibexpatMT.a
I had to comment out the else, as it (understandably) didn't know what to do with an .a file. I got an error message to the effect that it was skipping over my "incompatible" library in its search for -llibexpatMT. I realized that when I rebuilt the Expat library from scratch, I didn't specify a 64-bit platform. (I guess this was Creator's way of telling me this.)
So, I fixed that, rebuilt and now I get THESE errors:
I have absolutely no idea what all that nonsense is...anyone have a clue?Thanks...
-
wrote on 15 Aug 2019, 22:34 last edited by
Found the problem...turns out those symbols are looked for when this compiler switch is enabled, which it was in the VS project. I turned it off, and now the project builds...and runs when removed from the build directory, so I believe I have my long-coveted standalone image.
For those following along at home, I think you can ignore most of the above persiflage regarding the syntax for Windows libraries. What matters is that everything is of the same architecture: your application, your version of Qt, and any 3rd-party libraries you may use.
Thanks to all who looked at this.
-
Found the problem...turns out those symbols are looked for when this compiler switch is enabled, which it was in the VS project. I turned it off, and now the project builds...and runs when removed from the build directory, so I believe I have my long-coveted standalone image.
For those following along at home, I think you can ignore most of the above persiflage regarding the syntax for Windows libraries. What matters is that everything is of the same architecture: your application, your version of Qt, and any 3rd-party libraries you may use.
Thanks to all who looked at this.
1/24