How to force cmake not to configurate dependency directories? - cmake

I have a camke project as follows:
cmake_minimum_required(VERSION 3.14)
project(study)
## add 3d-party libraries
add_subdirectory(deps/eigen)
## self-defined directory
add_subdirectory(tests)
where /tests/ directory is made by myself, but /deps/eigen is a 3d-party directory.
Every time I make changes in /tests/CMakeLists.txt and run cmake .. in build directory. cmake reconfigures the 3d-party directory, i.e., rerunning deps/eigen/CMakeLists.txt again even though I did not change it. This is time-consuming. Is there a way to force cmake not to reconfigure 3d-party dependency directories if nothing is changed about it?

Related

Using third-party libraries with CMake

I want anyone who cloned the repository can build it immediately, and don't need to install the dependencies.
Therefore, I found several ways:
Use git submodule and add_subdirectory.
Use find_package to find the built libraries and the headers.
The first one takes much time to build, so I think the second might be better. To make people be able to build the project instantly, I put the the files in the project, but it saied it doesn't know the linker language. What's this? And how to solve?
Direstories:
Project Root
lib
SDL2
(generated files when install)
include
(headers)
src
(sources)
CMakeLists.txt
CMakeLists.txt:
# ...
list(APPEND CMAKE_PREFIX_PATH lib)
find_package(SDL2)
# ...

How to write the CMakeList file

cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(WINDOW CXX)
set(WINDOW_SRCS window.cpp)
add_executable(Window ${WINDOW_SRCS})
set(CMAKE_CXX_STANDARD 14)
find_library(OPENGL_LIB
NAMES lGLEW lglfw3 lGL lrt lm ldl lXrandr lXinerama lXxf86vm lXext lXcursor lXrender lXfixes lX11 lpthread lxcb lXau lXdmcp lXi lSOIL lassimp
PATHS /usr/lib /usr/local/lib
)
if(OPENGL_LIB)
target_link_library(Window ${OPENGL_LIB})
endif()
I am trying to write a CMakeList.txt file. I get an error in the generated Makefile
makefile:1: *** missing separator. Stop.
I've added tabs in the beginning of each line. I can't figure out where is wrong
The problem is that you haven't cleaned CMake generated files from the previous CMake configuration run.
Please remove the CMakeCache.txt file and Makefile and the directory CMakeFiles and if they exists the files cmake_install.cmake and CTestTestfile.cmake.
Now you can rerun the CMake configuration via cmake . again.
Then execute make and it should be ok.
In the answer I haven't attempted to improve your CMakeLists.txt, but just to make the issue you are encountering to go away.
Otherwise, as suggested by #roalz, you could use the find_package() to find OpenGL.
Another "improvement" could be to use out-of-source builds. In this way all the build results will be contained in one directory with no interference with the source tree. In this case, to start from a clean state and rerun the CMake configuration, you will only need to remove that build directory, and not all the single files created around. This is particularly useful for projects that have nested source directories (more than one level).

Setting CLion build and binary directory

I'm trying to build libwebsockets inside of my project in CLion. During build libwebsockets creates a header file that is required by other files and puts it in PROJECT_BINARY_DIR. CLion builds everything inside a random build directory it creates for the project and the header file ends up in that directory. I've tried:
Setting the websockets_BINARY_DIR variable
Setting the CMAKE_RUNTIME_OUTPUT_DIRECTORY variable
Setting CMAKE_LIBRARY_OUTPUT_DIRECTORY variable
Changing every variable in the CMake cache to point away from CLion's random directory
Changing the build output path setting in CLion's preferences
None of these work, Which leads me to my questions:
Is there a way to tell CLion where to build (not just where to put some of its output buthow to override the random directory it chooses).
If there isn't a way to tell CLion where to build, is there another variable that I should be setting?
I don't know how to set build dir.
Examples of how to set up bin directory with Clion below
set(dir ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}/bin")
or (separate for .exe, .dll, .lib):
set(dir ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${dir}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${dir}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}/bin")
Also I added link about how to set up build directory:
https://stackoverflow.com/a/28200869/3001953
But it soesn't work in my case (Clion 1.1).
You may also have a look at the Clion built-in path variables: https://www.jetbrains.com/help/clion/2019.2/absolute-path-variables.html

Specifying build directory within CMakeLists file

Is it possible to specify build directory within CMakeLists file? If yes, how.
My aim is to be able to call "cmake" within top level source directory and have cmake figure out the build directory.
Afaik, with CMake the build directory is always the directory from where you invoke the cmake or ccmake command. So if you want to change the build directory, you have to change directories before running CMake.
To control the location where executables, static and shared libraries are placed once finished, you can modifiy CMAKE_RUNTIME_OUTPUT_DIRECTORY, CMAKE_ARCHIVE_OUTPUT_DIRECTORY, and CMAKE_LIBRARY_OUTPUT_DIRECTORY respectively.
By design, there is not a way to specify that in CMakeLists.txt. It is designed for the user to be able to build the project in whatever directory they want. The typical workflow is:
Check out the project source code.
Go to desired build directory, or the source dir if you plan to do an in-source build.
Run cmake or ccmake to configure the project in that build directory.
Build your project.
All of the directories specified within your CMakeLists.txt should be relative to the ${PROJECT_BINARY_DIR} and ${PROJECT_SOURCE_DIR} variables. In this way, your code becomes buildable across different platforms, which is the goal of CMake.

How to point cmake at specific directory for library?

I have a CMake project where I am using a library and now I want to test my code with a different version of that library. I can set INCLUDE_DIRECTORIES (and possibly later also linking) in the below example. But because I only want to do this temporarily, I'd like to manually set this path with ccmake/cmake-gui.
How do I do this?
project(min_example)
cmake_minimum_required(VERSION 2.8)
find_package(OpenCV REQUIRED)
# Without the following line please:
INCLUDE_DIRECTORIES("/home/me/src/opencv/install/include")
add_executable(min_example main.cpp)
target_link_libraries(min_example ${OpenCV_LIBS})
This should be possible by setting the CMAKE_PREFIX_PATH variable upon configuring your build. In your project directory generate a test_build directory and run:
mkdir test_build
cd test_build
cmake -DCMAKE_PREFIX_PATH=/home/me/src/opencv/install ..
Setting the CMAKE_PREFIX_PATH variable will make the find_package(OpenCV REQUIRED) command pick your OpenCV installation in /home/me/src/opencv and set the OpenCV_LIBS and OpenCV_INCLUDE_DIR variables accordingly.
Alternatively you can edit a CMakeCache.txt file of an existing build directory with the CMake GUI editor and add the CMAKE_PREFIX_PATH definition there. You have to re-configure your project then.
Using config in find_package will restrict search path to OpenCV_DIR. This will use the cmake config that opencv generates at build time to setup paths to include and libs
set(OpenCV_DIR "<cusompath>" CACHE PATH '' ${SHOULD_FORCE_CACHE})
find_package(OpenCV REQUIRED CONFIG)