The best way to include assimp library using cmake - c++

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.

Related

gtest is linking to an installed library

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?

How to make a lib before making the program in CMAKE?

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.

How to link a library that was created from add_subdirectory in CMake?

I am trying to build a program using CMake that depends on a third party library. This third party library contains a CMakeLists.txt file so what I want to do is keep the source code of the third party library within my project directory, and build it using add_subdirectory(path/to/lib), and then link my target against the static library that the third party library generated.
my CMakeLists.txt:
cmake_minimum_version(VERSION 3.10)
project(my_project)
add_subdirectory("${CMAKE_SOURCE_DIR}/extern/somelib")
# my-code:
# somelib CMakeLists.txt file has a project name: SOMELIB
# which lets me access the directory where the files are built
# on windows it builds to /Release, on mac and linux it just builds
# to the binary dir
set(SOMELIB_LIBS "${SOMELIB_BINARY_DIR}/Release")
add_executable(my_program my_main.cpp)
target_link_libraries(my_program "${SOMELIB_LIBS}/SOMELIB.lib" "${SOMELIB_LIBS}/SOMELIBmain.lib")
I then make a build directory and from that directory I do:
cmake -G "Visual Studio 15 2017" ..
cmake --build .
The build command fails with a "LINK : fatal error LNK1181: cannot open input file 'extern/somelib/Release/SOMELIBmain.lib' ..."
My workaround for now has been to comment out the part that says "#my-code", build the somelib dependency first which generates the static libraries, and then uncomment out my-code and build again which then works correctly.
How can I tell CMake to build the subdirectory first, and then link against the static libraries that it generated?
Short answer: tell CMake that there is dependency between its targets.
target_link_libraries(my_program PRIVATE SOMELIB SOMELIBmain)
CMake will evaluate SOMELIBs locations for you and link my_program against SOMELIB and SOMELIBmain[1]. Works for both Debug and Release configurations and also for Linux.
You shouldn't have to worry where CMake places build files[2] and this is what so called "modern CMake" is trying to achieve. I will leave here just brief description but check link on the bottom of answer[3].
Anyway, the key concept is that whenever you create library/executable (target), you list its usage+build requirements and dependencies to other targets. You declare dependencies using target_link_libraries(<your_lib> KEYWORD <dependencies>). Such line will not only make <you_lib> link against listed dependencies, it will inherit their usage requirements (usually, public include directories) and order CMake to build dependent libraries before <your_lib>.
The beauty of it is that even if SOMELIB does not follow modern CMake ideas (does not declare build/usage requirements), you still should be able to do just with this single line.
[1] I assumed that CMake targets are named same as output library names, but it is not mandatory. For OP's case it turned out that static library targets are suffixed with -static, so he had to write SOMELIB-static SOMELIBmain-static
[2] Unfortunately, it is not so easy with shared libraries on Windows (DLLs)
[3] I'd start with this blog entry: https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/

ITK: Can't find ITKCommon-x.xx.dll when executing HelloWorld Example

i successfully built ITK 4.13 (as 'Release') on Windows 10 with the latest Visual Studio version (Visual Studio 15 2017 Win64 compiler). Then i tried to built the ITKHelloWorld example using the following CMakeLists.txt (as shown in the example by ITK):
#CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(HelloWorld)
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
add_executable(HelloWorld HelloWorld.cxx)
target_link_libraries(HelloWorld ${ITK_LIBRARIES})
Built runs without errors or warnings. Running the generated HelloWorld.exe file result in an ITKCommon-4.13.dll not found error.
The ITKCommon-4.13.dll was built by ITK, thus, i think i have to change something in the CMakeList file, but don't know what.
Any guess or solution?
Edit: The include(${ITK_USE_FILE}) expression in CMakeLists searches for UseITK.cmake, but this file is located in the source of ITK not in the build folder. Could this be a source of the error?
Edit2: Running a VTK Example also shows errors caused by not finding required .dlls.
There is no problem with your project. Windows can use dll libraries on runtime only if they are in PATH location. So there are two options: either you add bin/Release directory of ITK library to Windows's PATH system variable (the directory that contains all the ddls), or you just copy all the dlls from that directory to the one that contains your new application.
Precisely, you don't need to copy all the dlls, you can check by e.g. Dependency Walker, which ones are really needed.

CLion MinGW freeglut opengl library linking

I am trying to follow this guide to configure my freeglut and opengl .
I am used to the intellij enviroment via android studio so i would like to work in Clion.
I am stuck at the part....
Libraries: the OpenGL library "libopengl32.a", GLU library
"libglu32.a" and GLUT library "libfreeglut.a" are kept in
"\lib" directory. This directory is in the implicit
library-path. Nonetheless, we need to include these libraries in
linking. They shall be referred to as "opengl32", "glu32", "freeglut"
without the prefix "lib" and suffix ".a".
how do i add this in Clion ?
CLion uses cmake for building your projects. Follow below steps to add link libraries to your project.
Open the CMakeLists.txt file in your project and add,
target_link_libraries(<target executable> libopengl32.a libglu32.a libfreeglut.a)
to that file.
target executable is the executable which you want to link these libraries. Normally this is your project name as defined in add_executable.
Note: Cmake will show you an error if you place target_link_libraries before add_executable.