Header only libraries with scons - c++

I am new to scons so maybe my google-fu is really bad but I could not find a way to create a header-only C++ library. I know I can use CPPPATH to put directories in the include path but that is not ideal. My library libonlyheader depends on other external libraries like fmt and boost and I want executables and libraries built with these to transitively depend on fmt and boost as well. Essentially I am looking for a feature like the cmake's INTERFACE libraries.

Related

using shared library with custom file extension with cMake

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.

Archiving static dependencies in modern CMake project

I need to package a C++ library that links to some other static libraries, and I'd like to be able to ship the compiled files alone without the need to ship the transitive dependencies as well. To this effect, I'm following this guide regarding modern CMake techniques, and I've specified all the needed dependencies as PRIVATE, as they are not used in my library's exposed API.
The issue is that it seems that, despite having specified the dependencies as PRIVATE, the linker still does not include them in the output library, so if I try to link my library to an executable, the linker will complain about missing symbols (at least using MSVC). Is there a way to solve this?
I've already taken a look at this but I'm not sure how to integrate it in the existing INSTALL targets
Assuming that you are creating a static library:
You receive unresolved symbols because dependencies in static libraries are not resolved during their creation. Only when you link the static lib to an executable or shared library, the linker actually tries to resolve the required symbols (and will fail in your case).
So you need to combine your static libraries to a single one (as you already found out).
You should follow the approach of combining add_custom_command and add_custom_target that is outlined in the answers you linked to (https://stackoverflow.com/a/32888999/1228449).
Then use INSTALL( FILES ....) to add the combined library to your install commands, e.g.:
include(GNUInstallDirs)
INSTALL( FILES ${LIBNAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} )
EDIT:
Alternatively, create a shared library.
ADD_LIBRARY( mylibrary SHARED ...)
Then the required symbols of the privately used static libraries are resolved at link time of your library. Furthermore, only the symbols that your library actually uses, are integrated into your library (whereas the static library will contain everything).

How can I set cmake to look in different places for the headers and libraries

The project I'm working on is migrating everything over to cmake, but has a structure for how the library and include files for external libraries are stored. Is there any way to have cmake look in one place for the includes, and another for the library files? We are using 'find_package' to search.
find_package does exactly what the name suggest, search for a package, which usually is a set of headers and library files. The packages you search for may have different structures, but usually the find module search for a specific one, for example /lib for the libraries and /usr/include for the headers.
If you already know where to look for the headers or for the libraries you can set them with
include_directories()
link_directories()
It is also possible to set include and link per target with
target_include_directories()
target_link_libraries()
Maybe;
include_directories(...) for include folders
link_directories(...) for folders with libraries
There's also the target_include_directories(...) if you want more specific control.

Android NDK cmake and dependent libraries

I'd like to use a library (source codes from GH) in my JNI code. But the library depends on two other libraries (NTL and Boost) that are not available in Android NDK.
Now I am a bit confused and not sure if I understand correctly my following actions.
C++ code for Android is built into shared libraries (.so) for every platform (x86_64, armv7..). Does this mean that NTL, Boost and the lib I want to use must be compiled by me from source codes for these platforms too? If yes, how to do it correctly with cmake?
If I should build all the libs for specific platforms, how it is better to do, either as static libs (.a + headers) or as shared libs?
Do I really need to build NTL and Boost for all the platforms or I should do it just for the needed library?
Is Android.mk file required or can help with cmake? As I understand, it is used with "ndk-build" only.
Generally, if this sequence of actions is correct?
Build NTL for all platforms (.a + headers)
Build Boost for all platforms (.a + headers)
Build Library for all platforms (.so)
Add Library's .so-file as a dependency in CMakeLists for JNI project. (Do I still need dependent libs and headers or that dependencies will be incapsulated into lib?)
C++ code for Android is built into shared libraries (.so) for every platform (x86_64, armv7..). Does this mean that NTL, Boost and the lib I want to use must be compiled by me from source codes for these platforms too? If yes, how to do it correctly with cmake?
Yes, you'll need to build those libraries from source (or find a binary distribution for Android) if you want to use those libraries in your application. As for how to do that, you'll have to wait for someone else to answer or try Googling it. There are a handful of "how to build X for Android" tutorials out there, but I don't know if you'll find many for CMake since CMake is pretty new for Android.
If I should build all the libs for specific platforms, how it is better to do, either as static libs (.a + headers) or as shared libs?
That mostly depends on how many shared libraries you're building for your app. The ideal model for an app is to use a single shared library in your app and statically link in all of your dependencies (going to avoid linker bugs on old versions of Android, and will make your app as small as possible). If you have multiple shared libraries for your code, you'll need to use shared libraries for your dependencies to avoid ODR issues.
Do I really need to build NTL and Boost for all the platforms or I should do it just for the needed library?
You'll need to do it for any platform you need to use those libraries on.
Is Android.mk file required or can help with cmake? As I understand, it is used with "ndk-build" only.
CMake and ndk-build should both work, but you might have an easier time finding porting instructions for ndk-build due to CMake's relative youth in Android.

Build specific library from Boost C++ Library

I built the boost library in order to use the boost functions split and format.
I noticed that the split placed under the algorithm directory, but there is no library named 'algorithm' when I run --show-libraries to get the list of libraries.
When I built the whole boost, I didn't find which lib file to add to my project (I don't want to add the all the libs and headers).
How can I build this specific library?
Both boost::algorithm and boost::format are header only, so no need to build.
You will find both header files inside the include/boost/ folder:
include/boost/algorithm/algorithm.hpp
include/boost/format.hpp
When running bootstrap with --show-libraries:
The Boost libraries requiring separate building and installation are:
The algorithm library isn't listed and is even template for the STL equivalent -> header-only.