using shared library with custom file extension with cMake - c++

I working on a C++ application running on Linux. The project uses CMake.
It use a third party shared library. Unfortunately, the third party library doesn't end with .so.
And the CMake command find_library can't find the library.
Does anyone now how to force CMake to find libraries with a custom file extension? Or at least, how to configure GCC (through CMake) for linking with the library ending with a custom extension?
Thanks for any hint!

You can set the CMAKE_FIND_LIBRARY_SUFFIXES variable. From the documentation:
This specifies what suffixes to add to library names when the
find_library() command looks for libraries. On Windows systems this is
typically .lib and .dll, meaning that when trying to find the foo
library it will look for foo.dll etc.
Adding the custom suffix to it should do the trick.

Related

Static libraries in Qt 5.14 MinGW toolchain? (default Qt installation)

Just now I noted that the MinGW Toolchain that comes with the default Qt installation, at least Qt 5.14, comes with a lib directory with libQt5*.a files. Are those files static libraries?
I think so because:
They have a size similar to the ones that I get when I compile Qt statically for release.
$file ./libQt5Core.a outputs ./libQt5Core.a: current ar archive, which is the same that it outputs for the statically compiled ones.
If indeed they're static libraries, how can I tell QMake (for example editing the .pro file) to link to those instead of linking to the shared ones?
Are those files static libraries?
No. They are not static. Qt’s default online installer provides only shared libraries. That *.a files are so-called import libraries.
Import library is an .a or .lib library, but it only contains bit of information needed to tell the linker/OS how your program interacts with the dll’s.
If you need Qt static windows build for some reasons, you have some options:
HARD Build whole Qt (or needed modules) by yourself.
EASY Use vcpkg: vcpkg install qt5:x64-windows-static
With vcpkg you can create custom MinGW triplet if you need MinGW for some reason. But I suggest you stick with MSVC.

How to use cmake to check if some libraries exists before build our sources?

Usually, open source packages will have cmake to check if some headers or libraries exists or not, I wish my own project has this same functionality.
So I wish to know if cmake provides some command to check if some ".so"/".a"/".h" files exists in the current linux system or not, if not cmake will give me some hint to install them?
How does cmake support this?
Usually one would use the find_package(ABC REQUIRED) and then refer to it in your project. This will ensure that the dependent library is installed and cmake will fail if it is not.
You can find lot's of example on how this works in your cmake installation, for example C:\Program Files\CMake\share\cmake-3.13\Modules\FindZLIB.cmake will search for the zlib library by looking in the file system for normal places where this library would be installed and if it finds it will set these variables accordingly:
# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
# ZLIB_LIBRARIES - List of libraries when using zlib.
# ZLIB_FOUND - True if zlib found.
To achieve this header files are found using the cmake command find_path, and libraries (static and shared) are found using find_library.
To search for arbitrary library you can use find_library() command. Same task for headers is accomplished by find_file(). You can also search for executables with find_program().
As #Damian said in his naswer, many libraries provide "config" files, like FindBoost.cmake. Such libraries can be found by calling find_package(Boost) command. This command would locate and load config file and set corresponding variables.
You need to provide -config.cmake files to tell other projects where your libraries and headers are. Here, you will found what are you looking for.

Linking a library that not have a standarized name/extension

If you use the command target_link_libraries in cmake, when linking the linker will search for libraries which name match some criteria. For instace:
Using following command:
target_link_libraries(some_target some_lib)
In Linux the linker will search for: libsome_lib.so while in Windows the linker will search for some_lib.lib (in Windows I'm compiling a VS project generated from the cmake project).
Due to deployment requirements of my application the libraries have no extension and have to be called the same in both OS (e.g some_lib).
How can I tell cmake that search for such library?
I suppose that entering the full path will do the trick, but, there is another any way to do this?
Edit: Specifying the full path to the library does not work.
I didn't ever test that, but the CMake Wiki Docs refer these variables to specify library extensions:
CMAKE_FIND_LIBRARY_SUFFIXES
CMAKE_IMPORT_LIBRARY_SUFFIX
Windows-specific. Appears to be read-only. Use SET_TARGET_PROPERTIES.
CMAKE_LINK_LIBRARY_SUFFIX
Windows-specific.
CMAKE_SHARED_LIBRARY_SUFFIX
Appears to be read-only. Use SET_TARGET_PROPERTIES.
CMAKE_STATIC_LIBRARY_SUFFIX
Appears to be read-only. Use SET_TARGET_PROPERTIES.

The library file name with "lib" head can't be recognized in codeblocks and vs9 compiler

This environment is win7, codeblocks,vs9,boost1.52,
I have installed boost library with python library.It generates some library files.Such as "libboost_python-vc90-mt-gd-1_52.lib".
Then I write a test code to compile and link.But an error has occurred: can not open file "boost_python-vc90-mt-gd-1_52.lib".
The VS compiler don't recognized a library file name with "lib" head?How to do it better.
Adding a lib prefix at the start of the name is a Linux thing. On Windows there is a .lib at the end instead.
If the library is named "libboost_python-vc90-mt-gd-1_52", you have to give exactly that name to the linker.
First of all, Boost uses auto-linking under Windows. Thus, you only need to provide the location of the boost libraries, but not the names themselves.
Second, Boost uses different filenames for statically and dynamically linked libraries. The ones with lib prefix are for static linking, the ones without for dynamic linking.
By default, Boost uses static linking on Windows. Defining BOOST_ALL_DYN_LINK (there are library specific macros as well if you only want to dynamically link certain libraries) will enable dynamic linking.
From your error message, it seems that your project has BOOST_ALL_DYN_LINK enabled (either in the project settings, as a #define or in <boost/config/user.hpp>. If you prefer static linking, make sure to change/remove this setting.
Either way, make sure that the respective binaries are available and that their location (just the directory) is known to the linker.

Why doesn't Libtool want to link with a static library?

I want to build a shared library that uses ZipArchive using GNU Autotools but I'm having this problem:
Warning: linker path does not have real file for library -lziparch.
I have the capability to make that library automatically link in when
you link to this library. But I can only do this if you have a
shared version of the library, which you do not appear to have
because I did check the linker path looking for a file starting
with libziparch and none of the candidates passed a file format test
using a file magic. Last file checked: /usr/local/ZipArchive/ZipArchive/libziparch.a
The inter-library dependencies that have been dropped here will be
automatically added whenever a program is linked with this library
or is declared to -dlopen it.
If I build a static library or if I use a shared library of ZipArchive it works but the problem is that the makefile that comes with ZipArchive source code only builds a static library.
How can I force Libtool to link with a static library?
Generally, static archives are created with non-pic object files and they cannot be put into shared libraries.
What this message is telling you though, is that when a program links to YOUR library using Libtool, that -lziparch will get added to the link. So you don't need to change anything unless you're building a module for an interpreted language. In that case, you will have to build ZipArchive as a shared library. In addition, this wouldn't work on a platform like MS Windows where shared libraries (DLLs) have to resolve all their symbols at link time.
All that said, if your ziparch static lib is PIC code, you can use the -whole-archive flag when linking it to your library. This would be the least portable solution though.