CMake using the same external library in two projects - cmake

I have two projects who use the same external library (same version as well)
Using ExternalProject_Add in both project's CMakeLists downloads the lib twice to each of the project's folders and compiles them
Is there a way to download the lib to a shared location and use it on both project?
I'm aiming at saving download time and compile time
Thanks

Related

How to build an external library downloaded with CMake FetchContent?

I have a program that depends on an external library (SDL for example). I want CMake to take care of that dependency for me, so I was looking into FetchContent. As far as I understand, this module simply downloads the source code so that information on the external library is available at configure time. For example:
include(FetchContent)
FetchContent_Declare(sdl
GIT_REPOSITORY <...>
)
FetchContent_GetProperties(sdl)
# sdl_POPULATED, sdl_SOURCE_DIR and sdl_BINARY_DIR are ready now
if(NOT sdl_POPULATED)
FetchContent_Populate(sdl)
endif()
At some point, however, I want to build that source code and link it to my main executable. How to do it the "modern CMake way"?
The recommended way to build external libraries from source as part of your build depends on what the external lib provides build-wise.
External lib builds with cmake
If the external lib builds with cmake then you could add the lib to your build via a add_subdirectory(${libname_SOURCE_DIR}) call. That way cmake will build the external lib as a subfolder ("subproject"). The CMakeLists.txt file of the external lib will have some add_library(ext_lib_name ...) statements in it. In order to then use the external lib in your targets (an application or library that depends on the external lib) you can simply call target_link_libraries(your_application <PRIVATE|PUBLIC|INTERFACE> ext_lib_name) https://cmake.org/cmake/help/latest/command/target_link_libraries.html
I had a quick look at this github repo https://github.com/rantoniello/sdl - (let me know if you are referring to another library) and it actually looks like it is building with cmake and that it allows clients to statically or dynamically link against it: https://github.com/rantoniello/sdl/blob/master/CMakeLists.txt#L1688-L1740
So, ideally your applicaiton should be able to do
add_executable(myapp ...)
target_link_libraries(myapp PRIVATE SDL2-static) // Statically link againt SDL2
Due to their CMakeLists.txt file the SDL2-static comes with properties (include directories, linker flags/commands) that will automatically propergate to myapp.
External lib does not build with cmake
If a external lib doesn't build with cmake then one can try to use add_custom_target https://cmake.org/cmake/help/latest/command/add_custom_target.html to build the library. Something along the lines of:
add_custom_target(myExternalTarget COMMAND <invoke the repo's build system>)
You'd then need to set the target properties that are important for clients yourself via the the proper cmake functions set_target_properties, target_include_directories ... A great writeup how to get started with these kinds of things: https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/

linking shared libraries Scons

Can anybody suggest how to link shared libraries using SCons in this specific case.
I have 2 folder locations currently:
slib/ which contains only static libraries
dlib/ which contains only dynamic libraries
I can only add the prebuilt libraries to slib folder.
dlib folder is reserved for the dynamic libraries i create from source code.
My executable always links against this dlib folder.
Now in my case, I want to add some shared libraries (not built by me) into slib folder but I want those libraries to land in dlib folder so that my executable finds it when linking. In short i want my application (requiring those shared libraries) to use one folder when compiling and different folder when running.
Is there a way in SCons I can regenerate those libraries in a different folder ?
I am not allowed to manually copy from source to destination nor i can use
InstallAs( target = 'XYZ/dlib', source = 'ABC/slib' )

Share CMakeCache.txt file

In our project we are using some external libraries and using CMake to generate VS projects for build them. All libs exports cmake variables to configure them(include\exclude project, build as static\shared lib).
I want to share my CMakeCache.txt files with my teammates so that we have the same configuration for that libs.
Of course, I can't simply share my cache file because the are some absolute paths defined in it and it can't be reused on other machine. I understand, that cache files is not intended to be a sharable file. But what can I do except of including theese external lib projects to my cmake project and setting exported varibles there?
Thanks a lot!

Is .lib file required for applications with load time Dynamic linking?

It says that in case you use load time dynamic linking with DLL it looks up functions entries and other things from a .lib file.
However I cannot find any information on whether this .lib file is required only at compile time or if it needs to be shipped with the program executable for it to work
Lib files are linked into final executable or DLL - so no, you don't need to ship Lib files to users of the application.
If you are building DLL you may provide lib file for your DLL to developers to simplify using of your DLL.

cmake "exporting" shared library on windows

I'm writing a small library.
I'd like to build it as shared library and generate "MyLibraryConfig.cmake" file which then can be used by my other projects to find my library.
The only problem I have is to figure out the name/path to file which is used for linking under Windows - there are two files being generated: mylibrary.dll and mylibrary.dll.a.
So I'd like to generate MyLibraryConfig.cmake file with something like:
"set(MYLIBRARY_LIBRARIES /blah/blah/mylibrary.dll.a)"
so then MYLIBRARY_LIBRARIES can be used with target_link_libraries for my other projects.
How can I get name for this linkable file? I'd be nice if the solution was platform independed (returning .so wile on Linux and .dll.a on Windows)
thanks in advance
If you're planning on making your library available to your other projects without installing it then you want the CMake command export. For example:
export(TARGETS MyLib FILE ${CMAKE_SOURCE_DIR}/MyLibraryConfig.cmake)
This creates the file MyLibraryConfig.cmake in the same directory as your top-level CMakeLists.txt, and can just be included in other CMake projects.
If you're planning on installing your library, then you want to make use of install(EXPORT ...) instead:
install(TARGETS MyLib EXPORT MyLibraryConfig
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
install(EXPORT MyLibraryConfig DESTINATION cmake)
This will install the file MyLibraryConfig.cmake to <install path>/cmake, and can then be included by other projects.