Enable cmake options/flag after making the file - c++

I don't have much knowledge about cmake. I installed a package libfreenect2 following the instructions on their github page. The instructions were as follows-
Clone the repository. And follow the cmake step:
cd ..
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2
make
make install
However, after installing I realised the program/package that required libfreenect2 as a dependency required me to use:
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2 -DENABLE_CXX11=ON
You may have noticed, it required me to use an extra flag -DENABLE_CXX11=ON. How can I fix this? How can I set ENABLE_CXX11=ON after the whole make process has been completed? By the way what does -D do? (are these -DXXX things called options or flag)
In case your answer is to repeat the whole process again then kindly guide me through the step by step process of deleting the correct files. I don't want to delete other dependencies.
Here are some other stackoverflow answers relating to cmake-
set cmake option(), cmake option to include a directory, What does cmake do
SOLUTION - I used the accepted solution to enable the flag. Even though it worked for my problem (libfreenect2) still it will be amazing if someone could provide an answer which doesn't involve reinstalling.

My warm suggestion would be to repeat the process with that option ON.
First you should delete what was previously generated.
The sequence of commands to follow is the following:
rm -rf build
rm -rf $HOME/freenect2
just to be entirely sure you start from a "clean state".
I don't see the need to do rm -rf $HOME/freenect2 as that files/dir will be overwritten by the new install, but shouldn't hurt.
You can also try the suggestion in the SO post mentioned in one of the comments.
Then repeat the process from the root dir of libfreenect2:
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2 -DENABLE_CXX11=ON
make
make install
Alternatively, if you're entirely sure that you will build libfreenect2 always with that option ENABLE_CXX11=ON, you could explicitely set it ON once and for all in the CMakeLists.txt of libfreenect2, specifically changing the line:
OPTION(ENABLE_CXX11 "Enable C++11 support" OFF)
into
OPTION(ENABLE_CXX11 "Enable C++11 support" ON)
In this last case, you will just need to do
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2
make
make install
of course after you've cleaned as explained at the beginning.
About -D for CMake, it allows you to pass options. Directly from the documentation:
-D <var>:<type>=<value>
Create a cmake cache entry.
When cmake is first run in an empty build tree, it creates a
CMakeCache.txt file and populates it with customizable settings for
the project. This option may be used to specify a setting that takes
priority over the project’s default value. The option may be repeated
for as many cache entries as desired.
So if there's some project default options that one wants to change/overwrite than it can be done with this.

Related

Can someone expand what is meant by 'configure' and 'build' with CMake files

I am downloading this code from GitHub (subdivision-regression), and am getting stuck following the instructions:
To build doosabin_regression:
Run CMake with an out of source build.
Set COMMON_CPP_INCLUDE_DIR to the full path to rstebbing/common/cpp.
Set DOOSABIN_INCLUDE_DIR to the full path to rstebbing/subdivision/cpp/doosabin/include.
Set Ceres_DIR to the directory containing CeresConfig.cmake.
Set GFLAGS_INCLUDE_DIR, GFLAGS_LIBRARY and RAPID_JSON_INCLUDE_DIR. (Add -std=c++11 to CMAKE_CXX_FLAGS if compiling with gcc.)
Configure.
Build.
I have edited the CMakeLists.txt file to put the correct paths in. I then created a new directory called subdivision-regression-bin and ran:
cmake ../subdivision-regression/src
It completes this and displays:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/hert5584/RStebbing/subdivision-regression-bin
However, when I try and run the example code, it cannot find the files listed in CMakeLists.txt (I know they are the right paths as otherwise CMake does not run).
I have tried running:
sudo make install
But get the following error:
make: *** No rule to make target 'install'. Stop.
Any ideas why this isn't working? Have the above steps Configured and Built the files?
The ordered CMake idiom to understand is:
The Configure step
The Generate step (This is often subsumed in the Configure step, and not mentioned explicitly, as in this case.)
The Build step (in which you actually compile/link your code into libraries/executables)
Take a look at this resource for information about the configure and generate stages.
You didn't appear to perform the steps to set CMake cache variables. For these you have to use CMake command line options (-D specifically). So run CMake as something like this instead to set all six variables:
cmake -DCOMMON_CPP_INCLUDE_DIR=/rstebbing/common/cp -DDOOSABIN_INCLUDE_DIR=...[More CMake Cache variables]... ../subdivision-regression/src
For building, try just running make without sudo or install:
make

Merging make and cmake's make into build system

I have to merge cmake's makes and makes in our build systems. The build systems are supposed to be able to work with both options make and cmake. The problem is that cmake's make exports do not contain all variables and settings, which need to be set as make in our build systems. Basically, we use three complicated build systems for cross platform development and I do not like setting everything on many places, because then it is hard to maintain the system like that.
E g. makefiles from many coders in all build system contains include common file like:
include $(PROJECT_CONF_DIR)/common/something.mk
How to solute it by cmake? I do not like modifying coders' CMakeLists.txt (max. one row solution for them) and I also do not like modifying cmake exports into make files.
Basically, I need to put somewhere in cmake command or cmake's export (the best) some link which will lead to include all 'garbage' expecting by our build tool chains.
Make sure that CMakeLists.txt can contain many cmake subprojects and libraries.
e.g. Our build system from makefiles contains something like:
directories-default:
mkdir -p $(BUILD_DIR)
mkdir -p $(OBJ_DIR)
I need to implement it somehow in cmake include.
To be able to run make directories-default after configuration, you have to create a target. You can make a target that will call a custom command, which would run the shell commands you need.
add_custom_target(directories-default COMMAND mkdir -p "dir1" COMMAND mkdir -p "dir2")
The syntax above will result in a target that is always considered out of date, ie every time you run make directories-default (or make all), the commands will be executed. If you don't want to re-run the command every time you can use a custom command:
add_custom_command(OUTPUT "dir3" "dir4" COMMAND mkdir -p "dir3" COMMAND mkdir -p "dir4")
add_custom_target(directories-default2 DEPENDS "dir3" "dir4")
Here make directories-default2 will only run the commands the first time you run it. You can also create a dependency chain of commands using the DEPENDS argument in add_custom_command.

Why is this happening with cmake

I am working on a c++ project and I am using cmake as the build system, so my workflow here is make changes to code. then,
rm -r build
mkdir build
cd build
cmake -G "Unix Makefiles" ..
make
Now I added glew as a dependency to the project, so whenever I try to run make I get an error saying SDL.h not found(this was working before).After sometime I decided to check CMakeCache.txt.opened it using vim then :wq that's all I did now if I run make, my project is building successfully, I am not sure why this is happening, Can anyone tell me why?
ps: added gif of this event, check it out to get a clear picture
(the code i am working on is linked as well, this exact issue is in this commit "dd4452b45c733e0612bc5f3c632e9d1a08be8072")
link to gif
link to code
variables in cmake are limited to the scope of the directory they are in plus their subdirectories.
This, calling find_module() in the gamelib subdirectory does not find that module for use in the main directory.
The preferred way to propagate include directory dependencies is to add them to the target (in the gamelib directory), like this:
target_include_directories(gamelib BEFORE PRIVATE
$<BUILD_INTERFACE:${SDL2_INCLUDE_DIR}>
$<BUILD_INTERFACE:${GLEW_INCLUDE_DIR}>
)
target_include_directories(gamelib SYSTEM BEFORE PUBLIC
$<BUILD_INTERFACE:${SDL2_INCLUDE_DIR}>
$<BUILD_INTERFACE:${GLEW_INCLUDE_DIR}>
)
then you don't need to even mention them in any executable that uses gamelib.

Separate build directory for autotools projects not designed to use one

... Sorry, this has to be a duplicate, but I'm just running across answers for people who are making their own projects and can change the build system setup.
Can I always compile a program in a separate build directory, or must it be supported by the program's build system?
For vim, you compile using: "./configure && make && sudo make install". If I'm in vim.hg.build and run "../vim.hg/configure .....", I get :
../vim.hg/configure: line 6: cd: src: No such file or directory
For git, you compile using: "make configure && ./configure && make && sudo make install". I was hoping being in git.git.build and running "make --directory=../git.git configure" would work, but that leaves the configure file in ../git.git. Well, maybe just configure left behind isn't so bad, so I then tried "../git.git/configure" which successfully created config.status, config.log, and config.mak.autogen in the build directory. But running make gives:
make: *** No targets specified and no makefile found. Stop.
... Yes, the only Makefile is in git.git itself.
I even tried symlinking the entire directory by running:
for fl in `ls -a ../vim.hg`; do
echo "$fl"
ln -s ../vim.hg/$fl $fl
done
... But, vim's configure and make only modify existing files and subdirectories, so even though I can build this way, the build directory is left with nothing more than symlinks -- no actual separation.
Go cmake!
Out-of-tree building is a feature of Autotools that requires both Autoconf and Automake.
Vim and Git both only use Autoconf and not Automake, so they can't take advantage of that feature.
As a more general answer to your question: simple Autotools projects should work with out-of-tree builds automatically. When using certain advanced features, a bit of care must be taken to ensure that out-of-tree builds continue to work. Sometimes projects don't do this.
(Running make distcheck will test out-of-tree building, so it's a good idea to run it at least once before making a release.)

cmake -D <var>:<type>=<value> what does the parameter "-D" mean

I'm trying to use cmake to install opencv. In the opencv instruction page, I find the following example:
cd ~/opencv
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
As I understand it, I should use cmake to generate Makefile in the new directory I created, which in this example should be ~/opencv/release.
But I don't quite understand the last line. In cmake help, I find:
cmake -D <var>:<type>=<value> = create a cmake cache entry
What does it mean? Especially this part: "<var>:<type>=<value>", I don't understand why the example gives "CMAKE_BUILD_TYPE=RELEASE" and"CMAKE_INSTALL_PREFIX=/usr/local .."
Your help is greatly appreciated!
From the CMake Documentation:
-D <var>:<type>=<value>: Create a cmake cache entry.
When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project. This option may be used to specify a setting that takes priority over the project's default value. The option may be repeated for as many cache entries as desired.
The :<type> could be read as optional.
Maybe you can try:
cd ~/opencv
mkdir release
cd release
cmake -D'CMAKE_BUILD_TYPE=RELEASE' -D'CMAKE_INSTALL_PREFIX=/usr/local'
Just use ' ' surround the parameters and do not leave any blank between -D and ' and it can work.
I encountered some problems when I configure OpenCV with -D parameter.
And I think -D option just change some default parameters for compiling and installing the pkg.
Just as you inferred, CMAKE_BUILD_TYPE=RELEASE means you want to build a "Release" version of the opencv package, and CMAKE_INSTALL_PREFIX=/usr/local means you want to specify the install path of it while using make install command.
You might wonder why it's called -D. The D stands for define/definition. Using -DCMAKE_BUILD_TYPE=RELEASE defines CMAKE_BUILD_TYPE with value RELEASE in the CMake cache.
From the docs:
Create or update a CMake CACHE entry.
The main use of this to configure your build without changing the CMakeLists.txt file, for example, to switch between debug and release builds without editing files.
The reason it's not a variable, but a cache entry is for your convenience. Rerunning the command uses your previously set value.