[solved] building shared DLL creates static .a
-
wrote on 1 Sept 2014, 05:16 last edited by
While still playing around with Lua 5.2 compilation in QtCreator, I managed to get it working fine. Not that fine, actually... when I built the shared library (windows, mingw32) it produced the .dll and the .a file required to link the DLL in an application. Turns out, this .a file is just a static library that has nothing to do with the DLL. Also, when executing the clean step, the DLL file remains but .a file gets deleted - which shouldn't happen if qmake didn't evaluate it as temporary file.
So I compared the static and the shared build: the static library build produces a 239KB file while the shared library produces a 176KB file - substantially, they should be different. But I'm pretty sure that both of them are static and contain the same 'useful' code (read as: code added to an application upon linking) because, after linking and compiling the lua.exe binary (the lua interpreter CLI application) it should only work when the proper lua5.2.dll file exists. Instead the produced binary works just fine without the DLL.
To test out, I compiled the binary builds by linking it with first with the shared and after with static library. When comparing the output size and the MD5 hash, guess what: same size (170KB), same hash. I know for sure it shouldn't be like that because a manual compilation via cmd prompt using the included Makefile will produce a 19KB lua.exe that needs the DLL to properly work.
Next there is the qt project configuration that I am using. Lua 5.2.3 sources can be downloaded from "http://www.lua.org":http://www.lua.org (copy all Lua source files to the project directory). Please note that you need to set the buildTarget variable to what you want to build, and, you need to build the shared library (dll) first in order for the application binaries to be compiled.
@removing all qt related features, project is going to be compiled as plain C/C++ project
CONFIG -= app_bundle
CONFIG -= qt
CONFIG += releasebuildTarget options: lib, dll, interpreter, compiler
buildTarget = dll
Lua library version
DO NOT REMOVE VER_MAJ AND VER_MIN, they're used to properly link the DLL to the lua.exe and luac.exe applications!
VER_MAJ = 5
VER_MIN = 2
VER_PAT = 3HEADERS += lapi.h lauxlib.h lcode.h lctype.h ldebug.h ldo.h lfunc.h lgc.h llex.h llimits.h
lmem.h lobject.h lopcodes.h lparser.h lstate.h lstring.h ltable.h ltm.h lua.h lua.hpp
luaconf.h lualib.h lundump.h lvm.h lzio.hSOURCES += lapi.c lauxlib.c lbaselib.c lbitlib.c lcode.c lcorolib.c lctype.c ldblib.c
ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c
lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c
lundump.c lvm.c lzio.ccontains(buildTarget, lib){
message("Building static library");CONFIG += staticlib TEMPLATE = lib # lua5.2.a TARGET = lua$ DESTDIR = lib
}
contains(buildTarget, dll){
message("Building shared library");CONFIG += shared TEMPLATE = lib # lua5.2.dll TARGET = lua$ DESTDIR = dll
}
contains(buildTarget, interpreter){
message("Building Lua interpreter");TEMPLATE = app CONFIG += console DESTDIR = bin TARGET = lua SOURCES += lua.c # linking against dll/lua5.a LIBS += -L$$OUT_PWD/dll -llua$$VER_MAJ
}
contains(buildTarget, compiler){
message("Building Lua compiler");TEMPLATE = app CONFIG += console DESTDIR = bin TARGET = luac SOURCES += luac.c # linking against dll/lua5.a LIBS += -L$$OUT_PWD/dll -llua$$VER_MAJ
}
@Can you please tell me what am I doing wrong? I suspect there is something wrong in the DLL build, but I have no idea what...
-
wrote on 2 Sept 2014, 00:15 last edited by
Sorry for bumping up.. does anyone having any idea on what's wrong? Or, if you could please explain me how to get the proper .a file to use with the DLL it would be great.
-
Hi,
What do you get if you do a clean build ?
IIRC, when both static and shared lib are present in the same folder, there might be the possibility that the static is used by default for the linking part
-
wrote on 3 Sept 2014, 19:40 last edited by
Clean builds bring out the same result every time: lua5.a (176KB) and lua5.dll (175KB).
Yes, the static lib (lua5.a) should help linking the DLL to the application. But as I said previously, when using this lib, it just links statically and the DLL file is not needed in order to run the application. Here, see this:
http://www.mediafire.com/download/uw52klc7g987owm/interpreter.zip
The lua interpreter (lua.exe) compiled via cmd and makefile is only 19KB and requires the DLL (rename the DLL file to something different and try to run, you'll get an error). The same should happen when I compile from QtCreator but instead I get a 170KB exe file, and no DLL requirement. This means that the output file lua5.a is just the static lib version and it's not related to the DLL in any way.In the qmake project file I tried to add this to the DLL build:
@QMAKE_CXXFLAGS_SHLIB = -Wl,--out-implib,lib$$TARGET@
but seems it has no effect.EDIT
BTW, here are the compiled DLL and .a file:
http://www.mediafire.com/download/cyxypupxs1a49m9/dll.zip
Try linking against them yourself if you can and let me know if I am doing something wrong when linking...(note: links are to my mediafire account, you can trust they're not malicious)
-
Sorry, I misunderstood you. One thing I would add to your pro file is:
@
CONFIG -= staticlib static
@when you build the shared version, to ensure you don't have them lying around
-
wrote on 3 Sept 2014, 20:43 last edited by
Just did that, nothing has changed...
I can tell the "lib" and "dll" builds produce a different .a file. The dll build .a file is 176KB, while the one from the lib build is 239KB.
I really can't understand why they behave the same if they're different. Do you know any other flags that I could set/unset related to this? Maybe some flags that let me specify which output file name to set for the .a file?
-
TARGET is the correct variable to play with the library name.
Did you took a look of you application with e.g. Dependency Walker to see what it relies on to work ?
-
wrote on 3 Sept 2014, 22:18 last edited by
I just did that right now.
Compiling the interpreter with the .a file from the dll build creates no DLL dependency on lua5.dll. In fact all I get is it depends on KERNEL32.DLL and MSVCRT.DLL.
Runnind Dependency Walker on the interpreter built manually via makefile reports an additional dependency on LUA52.DLL.EDIT
Something that got in my mind is to have the Makefile included in the Lua sources, ported to the project file... I'm searching for guides but can't find much right now... -
wrote on 3 Sept 2014, 22:49 last edited by
what about adding @CONFIG += plugin@
-
wrote on 3 Sept 2014, 23:01 last edited by
Nope... I get exact same result as with "shared" or "dll", compiled files are the exact same.
I am trying now to get it compiled using the "vclib" template. It's not working right now, it says:
@00:56:57: Running steps for project lua523...
00:56:57: Starting: "C:\Qt\Versions\Qt-5.2.0-x86-ANGLE\bin\qmake.exe" D:\Progetti\Qt\lua523\lua523.pro -r -spec win32-g++ "CONFIG+=release" CONFIG+=shared
Project MESSAGE: Building shared library
Project MESSAGE: Building shared library
Project MESSAGE: Building shared library
WARNING: Unable to generate output for: D:/Progetti/Qt/Builds/lua523/[32-bit] Qt 5.2.0 ANGLE/Makefile.Release [TEMPLATE vclib]
WARNING: Unable to generate output for: D:/Progetti/Qt/Builds/lua523/[32-bit] Qt 5.2.0 ANGLE/Makefile.Debug [TEMPLATE vclib]
00:56:57: The process "C:\Qt\Versions\Qt-5.2.0-x86-ANGLE\bin\qmake.exe" exited normally.
00:56:57: Starting: "C:\Qt\Compilers\mingw32-4.8.2-win32-SJLJ\bin\mingw32-make.exe"
C:/Qt/Compilers/mingw32-4.8.2-win32-SJLJ/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'D:/Progetti/Qt/Builds/lua523/[32-bit] Qt 5.2.0 ANGLE'
mingw32-make[1]: Makefile.Release: No such file or directory
mingw32-make[1]: *** No rule to make target 'Makefile.Release'. Stop.
mingw32-make[1]: Leaving directory 'D:/Progetti/Qt/Builds/lua523/[32-bit] Qt 5.2.0 ANGLE'
Makefile:34: recipe for target 'release' failed
mingw32-make: *** [release] Error 2
00:56:59: The process "C:\Qt\Compilers\mingw32-4.8.2-win32-SJLJ\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project lua523 (kit: [32-bit] Qt 5.2.0 ANGLE)
When executing step 'Make'
00:56:59: Elapsed time: 00:02.@So yeah, I've got to check the docs about this template and see if can get it to work.
-
wrote on 3 Sept 2014, 23:10 last edited by
hm... it sound strange... what abut the settings that you have for shadow building? are you using Qt Creator?
-
wrote on 3 Sept 2014, 23:26 last edited by
Yes, I am using QtCreator 3 with precompiled qt 5.2.0 binaries (I have both ANGLE and OpenGL versions, both 32 and 64 bit) from the "qtx64 project":http://sourceforge.net/projects/qtx64/ and mingw32/mingw64 compiler.
My projects are located in D:\Progetti\Qt while my shadow builds are located in a subdirectory, D:\Progetti\Qt\Builds. I did not have any issues before due to this configuration though... -
wrote on 6 Dec 2014, 04:43 last edited by
I have finally found the problem to this, and I thought I would update this thread.
As often happens to many, I skipped the "check documentation" step. It was clearly advertized by Lua documentation that people should check the file "luaconf.h" to properly set up Lua.
Long story short, I should have done a #define LUA_BUILD_AS_DLL, so Lua source code would understand that the code is to be compiled into a shared library, not a static one. When adding that define (it can also be done in qmake via DEFINES += LUA_BUILD_AS_DLL ) it all works flawlessly.Even more, I have spent some time on a Qt Creator project that can help people compiling Lua in Qt Creator within clicks. You may want to check it here:
http://qt-project.org/forums/viewthread/50621/By the way, I just noticed I forgot to thank the people who answered this thread... I'm really sorry guys. If it still means anything to you, thank you very much!
-
wrote on 6 Dec 2014, 04:43 last edited by
I have finally found the problem to this, and I thought I would update this thread.
As often happens to many, I skipped the "check documentation" step. It was clearly advertized by Lua documentation that people should check the file "luaconf.h" to properly set up Lua.
Long story short, I should have done a #define LUA_BUILD_AS_DLL, so Lua source code would understand that the code is to be compiled into a shared library, not a static one. When adding that define (it can also be done in qmake via DEFINES += LUA_BUILD_AS_DLL ) it all works flawlessly.Even more, I have spent some time on a Qt Creator project that can help people compiling Lua in Qt Creator within clicks. You may want to check it here:
http://qt-project.org/forums/viewthread/50621/By the way, I just noticed I forgot to thank the people who answered this thread... I'm really sorry guys. If it still means anything to you, thank you very much!