I am using gtest for my library. I have two CMakeLists.txt, one for the main project and another one for the tests. In the main CMakelists.txt, I set
add_library(myLib::myLib ALIAS ${TARGETS_LIB_NAME})
Then in the gtest CMakeLists.txt, I link it as
target_link_libraries(test1 myLib::myLib)
But it keeps linking to installed version of myLib, not the one that is just built. Whenever I modify the header file, I have to delete the installed library in order to build the tests. What is a proper way to do this?
Related
I build my project using cmake (It is important for me to work both generators: Ninja and Visual Studio). And I need to add assimp library to my project. So, I added assimp from git to my project as git submodule and as suggested in the docs I added this lines to my CMake:
add_subdirectory(assimp)
target_link_libraries(project assimp)
I don't understand:
By default assimp compiles as shared lib, so why I should use target_link_libraries(rt assimp), if as far as i know it's link my executable with static library? And anyway after this linkage my .exe requires .dll.
Also, as alternative, I tried to compile assimp as static lib, as specified in the documentation I should use set(BUILD_SHARED_LIBS OFF). I added this flag to my main CMakeLists.txt. But it still compiles two files:
bin/Debug/assimp.dll
lib/Debug/assimp.lib
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(assimp)
target_link_libraries(project assimp)
I thought that I could choose one of them, but no: after linkage with static lib (target_link_libraries(rt assimp)) it's anyway requires .dll.
Note: .dll is uncomfortable for me, because I don't want to move the .dll to my .exe directory everytime. Also, variants like donwloading assimp from vcpkg or adding .dll to PATH don't work to me, because my main goal is: the user should just clone my git repo and compile the whole project with all dependecies using only one my CMakeLists.txt without additional actions.
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 would like to be able to dynamically compile a library that will be used by my project before compiling my project.
I am setting up a Vulkan project in C++ (with Clion) and would like it to be multi-platforms, I am using GLFW3.3 to make that happen.
Instead of building my library for each platform and putting the libs and .h in a folder that will be linked through the CMakeLists.txt, I would like to be able to CMAKE+make the library, then put the lib and .h where they need to be and then start compiling my program that will be using those.
GLFW has a working CMakeLists.txt (I manage to make it manually through the console) but I don't know how to tell CMAKE to make it etc.
I am used to using CMake to define path to libs and includes but my last project what also multi-platforms and I didn't like the way I handled the library (build manually etc).
So I am looking for a way in CMake to do everything at once even if it will take time to do so but I have no idea how that works.
Take a look at how Glitter does it:
option(GLFW_BUILD_DOCS OFF)
option(GLFW_BUILD_EXAMPLES OFF)
option(GLFW_BUILD_TESTS OFF)
add_subdirectory(Glitter/Vendor/glfw)
target_link_libraries(${PROJECT_NAME} ... glfw)
They just include the CMakeLists.txt file that GLFW provides and depend on it for the main target.
I need to build a standalone executable. The main problem is that this project relies on dll which I previously built on my system.
When I create the executable there should not be a dependence from these dll so I need to know if I can include them somehow in the program. To compile I'm currently using CMake which I believe is the best solution, but I haven't figured a way to accomplish this task yet.
Right now in my CMakeLists.txt file I do the following:
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
add_executable(myexe myexe.cxx)
target_link_libraries(myexe
${ITK_LIBRARIES} )
I omitted some instructions to focus on what's most important. When I compile it, it correctly works but it is not standalone as it still keeps using the dll (also tried with .a) installed on my system.
Thanks
A DLL is by nature dynamically linked to at runtime. Your only option is to use a static library (.lib on windows .
I have the following structure to a project I am working on:
---Library1
------build
------include
------src
------CMakeLists.txt
---Library2
------build
------include
------src
------CMakeLists.txt
---Executable1
------build
------include
------src
------CMakeLists.txt
Library1 is a library I am developing that needs to link with Library2 which is a 3rd party library. When I build Library1, I need it to automatically build Library2 and link with it. Executable1 will need to build and link with Library1. I'm not sure how to do with with Cmake, and I was wondering if anyone could guide me in the right direction. I think I may need to use the add_dependencies command or add_subdirectory but I'm not sure how to go about using them and making sure they are linked to my library. Any help would be appreciated.
I'd think the best commands here are likely to be add_subdirectory (as you suspected) and target_link_libraries.
I guess with your directory structure, I'd expect to see a "top-level" CMakeLists.txt in the root. In that CMake file, you'd invoke the subdirectories' CMakeLists using add_subdirectory.
I imagine both Library1 and Library2 are actual CMake targets, included via add_library, and similarly you have add_executable(Executable1 ...). In this case, you can add the following to Library1/CMakeLists.txt:
target_link_libraries(Library1 Library2)
CMake now automatically links Library2 whenever Library1 is specified as a dependency. If Library2 is modified, then it will be rebuilt automatically before being linked to Library1 again.
Likewise in Executable1/CMakeLists.txt you can then do:
target_link_libraries(Executable1 Library1)
Probably the only thing to watch for here is that the order of the add_subdirectory commands would need to be
add_subdirectory(Library2)
add_subdirectory(Library1)
add_subdirectory(Executable1)
so that the dependencies are defined before they're referred to in the target_link_libraries calls.
A final point which seems odd to me is that you have a build directory per target. Normally there should only be a need for a single build directory (preferably outside the source tree).