Mixing Shared and Static Libraries - premake

I'm using premake5 to build a complex application on multiple platforms. My application links against both static and shared/dynamic external libraries.
There seems to be significant build chain dependencies that break premake generated 'gmake' make files in this case.
Case in Point:
If you mix shared and static libraries in premake 'link' statements, GCC seems to get confused and expect your shared library references to actually be static libraries. When it can't find them the link stage fails. This is normally handled by prefixing your shared libs with '-Bdynamic'. Unfortunately there is no way to tell premake5 that an external link lib is static or dynamic, so you have to manually fixup the make files, which defeats the purpose of a build utility.
This is kind of a showstopper. I don't think you can just feed "-Bdynamic" into the linkoptions because it must be followed by the list of shared libraries.

Seems like a bug in gmake action (or at least a missing functionality)
For those, the best approach is to go to the Premake page on Github (https://github.com/premake/premake-core) and create a new issue.
And if you have the time to provide a small reproductible project (a static lib project, a dynamic one, and an application using both, each with only 1 cpp or some simple stuff + the premake script) and attach it to the issue, it would also be really appreciated (and much easier to treat this issue ^^)

Related

Static link with Premake

I'm using premake4 on Linux to build a project which links to a third party .a file.
Neither links {"foo"} nor links {"libfoo.a"} work, since premake generates a build script which incorrectly uses the flag -lfoo as if I'm linking a shared library. Using files {"libfoo.a"} will make premake ignore the file since it isn't C.
Premake4 is getting awfully old at this point. Is switching to Premake5 an option?
If not, one hacky workaround would be to use linkoptions to emit the link flags however you would like them to appear.

Static link sqlite in Lazarus

I am building an application with Lazarus where I use a sqlite database to store thousands of records. Right now I am linking to the sqlite library dynamically via the sqlite3.dll.
Is it possible to link to it statically? Where can I find the Lazarus compatible lib file to do that?
Note:
I only started using Lazarus and Free Pascal a month ago so something that might look very obvious to one, might not be for me. So bear with me a bit.
Cheers
Actual static linking is difficult since the TSQLite3Connection component is inherently designed to actively load the SQLite3 DLL. In other words, it's not linking against the library when you compile the program, the component is coded to dynamically load the DLL at run time.
If you are looking to have a totally self contained program, then you can accomplish this two different ways.
Create a new TSQLite3Connection component that links statically against sqlite3 instead of loading the DLL dynamically.
Include the sqlite3.dll as a resource in your program and have your program automatically deploy it before it runs.
Solution #1 is not trivial and not for the faint of heart. I've done it, and I intended to include a link to the component, but the result isn't stable. The problem is that you have to compile a static version of sqlite3, which isn't a real problem, but you have to do it with something like gcc under MinGW and that introduces issues. Compiling with gcc under MinGW means you have to then link in libgcc.a, and because FreePascal's internal linker doesn't know how to interpret stdcall symbols properly, you also have to link against MinGW's libkernel32.a, and libmsvcrt.a. The result just isn't stable. Crashes galore.
Solution #2 should be fairly easy, but the Lazarus maintainers make it a little hard. The part where you store the dll inside the executable as a resource is easy enough to do. And so is writing it out as a temp file. The problem is that you can't tell the TSQLite3Connection component where to find it after. So it looks in the executable's folder, or in system folders. Neither of which can necessarily be written to by the executable. The only place you can guarantee that your program will be able to write to is a temp folder. So what I did is created a new version of TSQLite3Connection component call TSQLite3DynConnection, meaning you can dynamically specify where the DLL is. I made a published property called ClientLibrary where you can specify the location of the dll (it doesn't have to end in .dll, so you can use system temp filename generation routines). You can get this component at: http://icculus.org/~kfitzner/misc/sqlite3dyndll.zip. It will compile against Lazarus 1.6.2 FP 3.0.0, or FP 1.0.6 / FP 2.6.0, which are the two versions I use.
I'll update this answer if I can get the statically linked version stable.
2 Dec 2016 update: I managed to get a static version stable.

Using MSBUILD like a classic MAKEfile -- how do I do this?

I'm frustrated by the lack of flexibility in the Visual Studio project/solution, but I realized that now that it uses MSBUILD it might be quite powerful but just doesn't expose that to the IDE. So I took a look at MSBUILD docs and don't know where to start! I wish there was a Nutshell book for that. Is there any good tutorial someone could point me to?
More specifically, here is the kinds of things I want to do:
Run a utility pre-processor to generate .CPP and .H files, which are then used by a regular C++ project. There are multiple inputs (to figure dependencies of; specifically should know if a normal .h file it uses has changed) and multiple outputs (at least one .cpp and one .h file) that are used as files in another project.
FWIW, the most complex case involves using Qt in a "normal" C++ project that can be built using VS Express 2010 or MSBUILD directly from a script on a server. Since that is a common library, there might be some guides or whatever to help? Note that a VS plug-in is not useful for the building stage, but could be used to initially generate project files that then rely only on MSBUILD and stuff included with the source code.
Would somebody please point me in the right direction?
--John
It gets worse from there, but that's my first goal.
I found the kind of information I was looking for in a book MSBuild Trickery: 99 Ways to Bend the Build Engine to Your Will by Brian Kretzler.
In the first 18 pages I found a few key pieces of information that, along with the on-line documentations I've already gone through, helps clear things up enough to try tackling my project. Details of interest include the processing order of how MSBuild reads and operates on the things in the file, quick points on when wildcard in items are expanded and how to handle generated files, and how to see what's happening in some practical cases or even step in the debugger.
FWIW, I managed to attack my problem without using the murky ".targets"/rules files that I have yet to understand, but only using better documented/exampled features (in particular, a Target that has wildcard items doesn't care that the file name extension is not in any ".target"; is simple enough to copy from example and allows the files to be seen in the IDE Project and added to the list using the IDE; again, the FileExtension there just works OK.)

Qt and zip files

I'm trying to write a simple Qt app that will access zip files and read the content of these zip files (the content are text files). Many posts says that Quazip is the solution.
Being new to Qt and coming from .Net background, I really don't know how to use the Quazip, I downloaded the Quazip source but I'm not sure, should I compile it or should I use the source code in my project. I really have no clue.
Any help is much appreciated.
Regards.
It seems as you have various options. You can use source code immediately by copying the relevant files into your project. By default however a static library is compiled when you run
> make install
and in that case you need to add the relevant path to your .pro file so that it finds is static library.
Well, you have several options:
Just add the sources to your project. Pros: you can modify them if you want without affecting your other projects. Cons: updating QuaZip is probably going to be a maintenance headache.
Compile it as a static library (qmake CONFIG+=staticlib). Pros: updating is easier as you don't have to deal with structural changes, only recompile QuaZip and rebuild/relink your projects. Cons: you still have to recompile and relink.
Compile QuaZip as a shared (DLL) library. Pros: updating is extremely easy provided that the new version maintains binary compatibility, plus the code is shared among various applications running at the same time. Cons: it will break everything (that is, until you rebuild/relink your apps) if the new version doesn't maintain binary compatibility.
If you just need to read some zip files in some random project, any of these three will do fine. You probably won't have to update QuaZip either, unless you find some bugs that need to be fixed.
As for the binary compatibility: it is guaranteed that third level version changes (x.y.z1 -> x.y.z2) are binary compatible. As for minor version changes (x.y1 -> x.y2), they probably won't be binary compatible for some time, until the Pimpl idiom is implemented properly.

Dynamic linking in zOS

i have to create a dynamically linked library in zOS . What are the options to be passed to the compiler.
Also, how to check if a library in zOS is dynamically linked[dependent] on other libraries.
we have ldd in linux, which shows this linkage. Do we have a 'ldd' equivalent in zOS land?
You don't say it directly, but I assume you mean a C/C++ DLL. You can do shared libraries in other languages as well (even assembler), but the steps would be different.
First, you need to decide what you want to export. A lot of the IBM examples use the compiler EXPORTALL directive, but be aware this can lead to very slow executables, depending on your coding style. If you don't do EXPORTALL, you'll need #pragma export for anything (code or data) you want to export. Don't forget you can export data (variables) as well as executable functions...sometimes you'll need this to share data with DLL functions.
Then, you need to set your compile options on both client (caller) and DLL to use the DLL linkage...this is the -Wc,DLL compile option and when enabled, it generates extra logic in your program to load and manage the DLL. It's a good idea to also include #pragma csect for your exported functions if you think you'll ever have the need to update the DLL without replacing it entirely.
When you link your DLL, be sure to specify the -Wl,DLL option (there are lots of ways...this part is different if you link in batch - I'm assuming you're building in a make file of some sort). The link will generate the actual DLL, as well as a "side deck" containing "IMPORT" statements for all of your exported functions. You'll need these to link any of the client-side programs that you expect to call the DLL. For example, if your imports are in a file called AAA.x, c89 -Wc,DLL myapp.c AAA.x would compile the calling code, with awareness that functions in AAA.x are off in some sort of DLL.
To your point about DLLs calling other DLLs, don't forget that a DLL can both "serve" and "consume" functions...by including the side deck for functions in other DLLs, you can have a DLL that provides some functions while calling other DLLs to access others.
The actual DLL itself can be in several places depending on the nature of your app. If you're UNIX Services friendly, it's just an executable in LIBPATH. It can also be STEPLIB, LNKLST, LPA and so forth.
If you need to, you can access your DLLs explicitly at runtime using dlopen(), dlsym() and so forth. Generally, this lets you control exactly which DLL you're using (sometimes handy if the user can provide one himself), and it gives you what amounts to function pointers that are resolved within the DLL.
There are some other basic things to consider when linking, such as ensuring that your code is reentrant. Most of these are spelled out in the IBM documentation, and if you build with things like "c89" (or equivalent), the correct options are usually setup for you automatically (in fact, to get a good idea of what's going on, turn on the verbose output and see all the parameters for yourself).
If you need to build up a cross reference of what calls what, the UNIX Services "nm" command can give you that information. If you produce detailed link-edit listings, all the data is in there too when you're building your DLLs.
Good luck!

Resources