I have a set of files (cxx and hpp) that I would like to make into a shared lib. I would like to link that shared lib against My main application file (InjMain.cxx) to create the final executable.
Below are the following set of CMake commands that I use.
set(INJ_SRC
src/functions/AFunction.cxx
src/functions/BFunction.hpp
src/functions/CInterface.hpp
src/functions/DImpl.hpp
src/functions/EInterface.hpp
)
add_library(INJ_LIB SHARED ${INJ_SRC})
add_executable(TEST_INJ src/InjMain.cxx)
target_link_libraries(TEST_INJ ${INJ_LIB})
The above doesn't seem to work. However if I use
add_executable( TEST_INJ ${INJ_SRC} src/InjMain.cxx)
that seems to be working ok. What am I doing wrong?
Related
I already have a lib.a. I just want to linking this lib into my project. I tried to use find_library() and target_link_library() how shown in this tutorial [https://www.jetbrains.com/help/clion/quick-cmake-tutorial.html#static-libs][tutorial] . But when I write this find_library(SRC_INsddfsdfT lib/src_intfdssfd libsdfsdfsd)
target_link_libraries(${PROJECT_NAME} LINK_PUBLIC /lib/libsrc_ini_lib.a) from step 6. I have find then method find_library() always isn't working. I can write any strings in it and this method does't get errors. However method terget_link_library() always does got me 1 error Cannot specify link libraries for target "RightTests" which is not built by
this project.
Please help me with this trouble.
P.S. I don't how to linking library without sequence inside add_library(${LIB_NAME} STATIC ${SOURCES} ${HEADERS})
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/
I have a specific CMake project I would like to build as both a static lib and a shared object (Linux only). The relevant part of the CMake file:
...
# Static lib
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
# Build shared object in Linux only
if(UNIX)
set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
add_library("${PROJECT_NAME}_SHARED" SHARED ${SOURCES} ${HEADERS})
endif(UNIX)
link_directories(${ILI_EXTERNAL_LIB_DIRS})
target_link_libraries(${PROJECT_NAME} ${ILI_EXTERNAL_LIBS} IliLib PlantModel)
I can figure out why the shared object is not being built, when I add a message within the Unix block, it gets printed during the make build. The rest of this cmake file only sets variables and declares the project name.
Any tips for how to go about debugging this issue? On both Windows and Linux, it only builds the static lib at present.
Edit:
Link to CMake and Make log outputs.
The solution was suggested by #Tsyvarev, trivial error on my part.
The static lib was being built because it was a dependency of another build target. I had not explicitly run "Make" on the SimulatorLib project.
CMake messages appear in the CMake log irrespective of whether that particular project is being built.
I have the following dependencies:
add_library(lib)
add_library(ilib INTERFACE)
add_dependencies(ilib lib)
target_link_libraries(ilib INTERFACE
"-Wl,--whole-archive $<TARGET_FILE:lib> Wl,--no-whole-archive")
add_executable(exe ilib)
When I changed some source codes of lib, the lib as expected was compiled and built again. However, exe did not link the new lib. If I use add_executable(exe lib), then exe will always link the new lib. (The reason why I use the ilib is that I need to process lib before using it.)
You expect lib to be propagated when one links with ilib.
But command add_dependencies doesn't add properties for propagation. You need
# Linking with `ilib` will transitively link with a `lib`
target_link_libraries(ilib INTERFACE lib)
When need to use --whole-archive option for linker, it could be done in the following way:
target_link_libraries(ilib INTERFACE "-Wl,--whole-archive" lib "Wl,--no-whole-archive")
When parse arguments for given function, CMake will finds argument lib to be a target name, and will add proper file-level dependency. With that dependency the executable will be relinked whenever the library file has been changed.
I have a very basic CMake project that uses Google Test. I want to build it as a dll, and the CMakeLists.txt file in gtest indicates that BUILD_SHARED_LIBS needs to be set in order for gtest to be built as a shared library.
My problem is that I cannot figure out how to set BUILD_SHARED_LIBS so that it shows up. If I use cmake-gui an set the value in the cache, then I do indeed see the generated build attempt to create a dll.
Below is my CMakeLists.txt. I would appreciate any suggestions on how to make it set BUILD_SHARED_LIBS.
CMAKE_MINIMUM_REQUIRED(VERSION 3.0 FATAL_ERROR)
PROJECT(MyProj)
SET(BUILD_SHARED_LIBS ON)
ADD_EXECUTABLE(MyProj main.cpp)
ADD_LIBRARY(MyLib STATIC mylib.cpp)
TARGET_LINK_LIBRARIES(MyProj MyLib)
ADD_SUBDIRECTORY(gtest-1.7.0)
Google Test will only build as a shared library (DLL) if BUILD_SHARED_LIBS is set. Hence I want to set that in this CmakeLists.txt file. I know how to make my own library shared, but I can't figure out how to set that variable in a way that the gtest CMakeLists.txt file sees it.
In your code
ADD_LIBRARY(MyLib STATIC mylib.cpp) // Your code STATIC lib
Change above line to this
ADD_LIBRARY(MyLib SHARED mylib.cpp) // Shared Lib is added