Building Dynamic Library for a complex project using makefiles on Linux - linux

I'm trying to build a shared library on Linux having different modules, and since source files are spreded in different sub directories, I am having trouble figuring out how to create scripts and makefiles to compile the whole project as a single Dynamic shared Library with modules depending on other modules.
Could anyone please give me any examples or tutorials to help me ?

I always found this article useful:
Static, Shared Dynamic and Loadable Linux Libraries
From there you'll want to do a tutorial on Make.

Related

Building a nodejs addon without modifying C library

I have searched a lot here about the steps to create a add-on for a C library. I see there are plenty of tutorials online on how to build a add-on using the node-gyp. All of them involved creating a .cc file which is built by the node-gyp. Is there a way to build .c files directly as well. I do have a custom c library (.c, .h and also a compiled .dll for the same files). Is there a way to directly use the functions from the custom library without making any modifications to the source files? Most of the examples online have the v8 and uv header files included in it. The C library I have is a more generic and cannot be modified by me. Any help would be greatly appreciated. I did try to use node-ffi but it doesnt seem to be working with the newer versions of node-js.
Thanks,

how to release a module in Haskell that can be used in another program?

I'm a beginner of Haskell, and I got a question here, how to release or build a module which can be used in another program ?
For example, when I use Java, I can write some classes, some functions and make it to be a jar that can be use in another program. So , how does this go with Haskell? Is there necessary to use the same functions, modules with the source code ?
And thanks.
If you're fine with sharing your library and its source code with everyone, it is common to upload it to Hackage. Other projects built with any common Haskell build tool know how to interface with Hackage packages
If you want to selectively share your library and its source code, you can upload it to a private or public github repository, and it could be used as a stack dependency
If you want to share the library locally with yourself, stack supports depending on local paths
If you wish to share your library without sharing source code, you can expose a C-api and make a DLL

Proper way to make and use Rust shared libraries?

I am working on bindings for a cpp library.
To do this I wrote a capi / wrapper for the library and compiled that to a shared lib (.so file).
My question is, how do I then use and integrate this file into cargo without forcing the user to install it? Currently I build the cpp via a Makefile called from the build variable in Cargo.toml, but I am unsure what to do with the compiled lib.
For testing, I can either use rpath or LD_LIBRARY_PATH to point the executable to the right location, but this will not work when distributing a library.
How are people managing this?
First of all, determine whether you really need a shared library. It's not clear from your question, but if you compiled your own wrapper into a shared library, that's probably unnecessary - you can compile your code into a static library and link it directly into your executable.
Moreover, you can try to link that third-party library statically too. I don't think this should be hard. And yes, you need to use build command in the manifest to do all of this now.
However, if you still need to use a shared library and you don't want the end user to install it herself (which is strange, because that's the point of shared libraries), you have to distribute it manually. For example, you can write a makefile which assembles an archive which your users may extract and use. For your program to find the library correctly you will either have the user to install this archive into the system root directory (e.g. /usr on linux; then this shared library will be located automatically) or you will have to write small shell script wrapper around your executable which will locate the shared library and set appropriate LD_LIBRARY_PATH.
I'd go for the first path. Usually all major platforms provide means to create installation packages (deb/rpm/pkg.tar.xz/whatever on Linux, brew on Mac, windows installer on Windows, though on Windows you can just put your shared library in the same directory as the executable and it will work). You just have to create packages for the platform your users work on, so your program will be installed in correct directories and your shared library will be resolved automatically.

Difference between .so file and .a file?

I have read that .so is a dynamic library file and .a is a static library file.
While building openssl i gave the option ./Configure no-shared and it created a lot of .a files.
So, my question is will the other packages like apache will be able to use .a files from openssl?
for example libcrypto.a,
someone please advice me if im going enirely through wrong path.
Basically the static library can be compiled into another application at link time. In your example Apache could use libcrypto.a during build time and include it in the Apache httpd application.
A dynamic .so library can be loaded and unloaded at runtime and you have a better flexibility to change what Apache should support without recompiling the Apache binaries.
Using Apache as example the dynamic loading of .so files are described in the Dynamic Shared Object (DSO) section in the documentation. You can also find links to the installation section which describe how to include static libraries at build time.
There is a good question about this that could be good to read, and that provide mote details in the subject.
Difference between shared objects (.so), static libraries (.a), and DLL's (.so)?
If A.a is static library and two different programs want to use it. A.a is created two times for each program. while If A.so is dynamic library than two programs access same file.
Its mean that you are using reference in library.
If your library is going to be shared among several executables(like apache and openssl), it often makes sense to make it dynamic to reduce the size of the executables. Otherwise, definitely make it static.
In your case you must create dynamic library
Please read -
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html.
It is a very good tutorial with example.
you will learn -
what is static library (.a) and how to make it.
what is shared library (.so) and how to make it.
difference with .ddl (windows os)

How to make binary distribution of Qt application for Linux

I am developing cross-platform Qt application.
It is freeware though not open-source. Therefore I want to distribute it as a compiled binary.
On windows there is no problem, I pack my compiled exe along with MinGW's and Qt's DLLs and everything goes great.
But on Linux there is a problem because the user may have shared libraries in his/her system very different from mine.
Qt deployment guide suggests two methods: static linking and using shared libraries.
The first produces huge executable and also require static versions of many libraries which Qt depends on, i.e. I'll have to rebuild all of them from scratches. The second method is based on reconfiguring dynamic linker right before the application startup and seems a bit tricky to me.
Can anyone share his/her experience in distributing Qt applications under Linux? What method should I use? What problems may I confront with? Are there any other methods to get this job done?
Shared libraries is the way to go, but you can avoid using LD_LIBRARY_PATH (which involves running the application using a launcher shell script, etc) building your binary with the -rpath compiler flag, pointing to there you store your libraries.
For example, I store my libraries either next to my binary or in a directory called "mylib" next to my binary. To use this on my QMake file, I add this line in the .pro file:
QMAKE_LFLAGS += -Wl,-rpath,\\$\$ORIGIN/lib/:\\$\$ORIGIN/../mylib/
And I can run my binaries with my local libraries overriding any system library, and with no need for a launcher script.
You can also distribute Qt shared libraries on Linux. Then, get your software to load those instead of the system default ones. Shared libraries can be over-ridden using the LD_LIBRARY_PATH environment variable. This is probably the simplest solution for you. You can always change this in a wrapper script for your executable.
Alternatively, just specify the minimum library version that your users need to have installed on the system.
When we distribute Qt apps on Linux (or really any apps that use shared libraries) we ship a directory tree which contains the actual executable and associated wrapper script at the top with sub-directories containing the shared libraries and any other necessary resources that you don't want to link in.
The advantage of doing this is that you can have the wrapper script setup everything you need for running the application without having to worry about having the user set environment variables, install to a specific location, etc. If done correctly, this also allows you to not have to worry about from where you are calling the application because it can always find the resources.
We actually take this tree structure even further by placing all the executable and shared libraries in platform/architecture sub-directories so that the wrapper script can determine the local architecture and call the appropriate executable for that platform and set the environment variables to find the appropriate shared libraries. We found this setup to be particularly helpful when distributing for multiple different linux versions that share a common file system.
All this being said, we do still prefer to build statically when possible, Qt apps are no exception. You can definitely build with Qt statically and you shouldn't have to go build a lot of additional dependencies as krbyrd noted in his response.
sybreon's answer is exactly what I have done. You can either always add your libraries to LD_LIBRARY_PATH or you can do something a bit more fancy:
Setup your shipped Qt libraries one per directory. Write a shell script, have it run ldd on the executable and grep for 'not found', for each of those libraries, add the appropriate directory to a list (let's call it $LDD). After you have them all, run the binary with LD_LIBRARY_PATH set to it's previous value plus $LDD.
Finally a comment about "I'll have to rebuild all of them from scratches". No, you won't have to. If you have the dev packages for those libraries, you should have .a files, you can statically link against these.
Not an answer as such (sybreon covered that), but please note that you are not allowed to distribute your binary if it is statically linked against Qt, unless you have bought a commercial license, otherwise your entire binary falls under the GPL (or you're in violation of Qt's license.)
If you have a commercial license, never mind.
If you don't have a commercial license, you have two options:
Link dynamically against Qt v4.5.0 or newer (the LGPL versions - you may not use the previous versions except in open source apps), or
Open your source code.
The probably easiest way to create a Qt application package on Linux is probably linuxdeployqt. It collects all required files and lets you build an AppImage which runs on most Linux distributions.
Make sure you build the application on the oldest still-supported Ubuntu LTS release so your AppImage can be listed on AppImageHub.
You can look into QtCreator folder and use it as an example. It has qt.conf and qtcreator.sh files in QtCreator/bin.
lib/qtcreator is the folder with all needed Qt *.so libraries. Relative path is set inside qtcreator.sh, which should be renamed to you-app-name.sh
imports,plugins,qml are inside bin directory. Path to them is set in qt.conf file. This is needed for QML applications deployment.
This article has information on the topic. I will try it myself:
http://labs.trolltech.com/blogs/2009/06/02/deploying-a-browser-on-gnulinux/
In a few words:
Configure Qt with -platform linux-lsb-g++
Linking should be done
with –lsb-use-default-linker
Package everything and deploy (will
need a few tweaks here but I haven't yet tried it sorry)

Resources