Changing CMake files standard location - build

I have a source directory with a folder called "phantom-dir/" where I put all generated files I don't need. I want to put all generated files by CMake inside this phantom directory (together with other generated and "ugly" files).
A mini example:
$ mkdir cmake-test
$ cd cmake-test
$ echo 'message("Hello World!")' > CMakeLists.txt
$ cmake . | grep "Hello"
Hello World!
$ tree
.
├── CMakeCache.txt
├── CMakeFiles
│   ├── CMakeCCompiler.cmake
│   ├── cmake.check_cache
│   ├── CMakeCXXCompiler.cmake
│   ├── CMakeDetermineCompilerABI_C.bin
│   ├── CMakeDetermineCompilerABI_CXX.bin
│   ├── CMakeDirectoryInformation.cmake
│   ├── CMakeOutput.log
│   ├── CMakeSystem.cmake
│   ├── CMakeTmp
│   ├── CompilerIdC
│   │   ├── a.out
│   │   └── CMakeCCompilerId.c
│   ├── CompilerIdCXX
│   │   ├── a.out
│   │   └── CMakeCXXCompilerId.cpp
│   ├── Makefile2
│   ├── Makefile.cmake
│   ├── progress.marks
│   └── TargetDirectories.txt
├── cmake_install.cmake
├── CMakeLists.txt
└── Makefile
4 directories, 20 files
By default, all CMake files (CMakeCache.txt, cmake_install.cmake, Makefile, CMakeFiles) are written in the working directory. But, I want something like that:
$ mkdir cmake-test
$ cd cmake-test
$ mkdir phantom-dir
$ echo 'message("Hello World!")' > CMakeLists.txt
$ // editing CMakeLists.txt to set some cmake variables.
$ cmake . | grep "Hello"
Hello World!
$ tree
.
├── phantom-dir
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │   ├── CMakeCCompiler.cmake
│ │   ├── cmake.check_cache
│ │   ├── CMakeCXXCompiler.cmake
│ │   ├── CMakeDetermineCompilerABI_C.bin
│ │   ├── CMakeDetermineCompilerABI_CXX.bin
│ │   ├── CMakeDirectoryInformation.cmake
│ │   ├── CMakeOutput.log
│ │   ├── CMakeSystem.cmake
│ │   ├── CMakeTmp
│ │   ├── CompilerIdC
│ │   │   ├── a.out
│ │   │   └── CMakeCCompilerId.c
│ │   ├── CompilerIdCXX
│ │   │   ├── a.out
│ │   │   └── CMakeCXXCompilerId.cpp
│ │   ├── Makefile2
│ │   ├── Makefile.cmake
│ │   ├── progress.marks
│ │   └── TargetDirectories.txt
│ ├── cmake_install.cmake
├── CMakeLists.txt
└── Makefile
4 directories, 20 files
That means: the Makefile in the current directory (to make, "cmake . && make"), but the remaining generated files inside the "phantom" directory.
I know I can make it with:
$ cd phantom-dir/
$ cmake ../
But it's a little tiresome for me to do it each time I want to re-compiling or remake cmake, above all taking into account that I'm modifying many times my CMakeLists.txt.
Which variables I have to set in the CMakeLists.txt file in order to achieve it?

You could make use of the undocumented CMake options -H and -B to avoid leaving your source dir. -H specifies the path to the main CMakeLists.txt file, and -B specifies the path to your desired build directory.
cmake -H. -Bphantom-dir
Note that these are undocumented and so I suppose could change at any time the Kitware guys feel like.
To build your project without leaving your source dir, you can make use of the (official) option --build This is a cross-platform way to invoke your chosen build tool, and you can pass whatever flags you want to this tool. e.g.
cmake --build phantom-dir -- -j3

Related

Running all tests for a multi-binary project

Consider a multi binary project with the following structure.
.
├── bin1
│   ├── config
│   │   ├── config.go
│   │   └── config_test.go
│   └── utils
│   ├── utils.go
│   └── utils_test.go
├── bin2
│   ├── config
│   │   ├── config.go
│   │   └── config_test.go
│   └── utils
│   ├── utils.go
│   └── utils_test.go
├── cmd
│   ├── bin1
│   │   └── bin1.go
│   ├── bin2
│   │   └── bin2.go
│   └── bin3
│   └── bin3.go
├── go.mod
├── go.sum
└── shared
├── db
│   ├── db.go
│   └── db_test.go
├── model
│   ├── modela.go
│   ├── modela_test.go
│   ├── modelb.go
│   └── modelb_test.go
└── utils
├── utils.go
└── utils_test.go
This project has three binaries bin1, bin2 and bin3. Packages in the /shared directory (e.g. package shareddb, sharedmodel and sharedutils) are shared with binary specific packages (e.g. package bin1config, bin1utils in /bin1 directory and package bin2config, bin2utils in /bin2 directory).
How can we run
all the unit tests in this project altogether?
all the tests in a package (e.g. in shared/model)?
each tests separately?
I attempted the following.
Running go test from the project root resulted in no Go files in /projectroot.
# run all tests
go test ./...
# run all tests under a specific directory (including subdiretories)
go test ./bin2/...
# test package located in specific directory
go test ./shared/model
# test package that has specific import path
go test projectroot/shared/model
# test package in current working directory
go test
# ditto
go test .
# test package in parent directory
go test ..
# run a specific test within the package under test
go test -run=X
# run a specific sub-test within the package under test
go test -run=X/Y
For more details on the go test command, see Test packages.
For more details on the [packages] argument to go test, see Packge lists and patters.
For more details on the testing flags, see Testing flags.

VSCode C++ IntelliSense/autocomplete is not working for OpenCV C++

OpenCV is installed from the source on my Linux (Ubuntu 18.04.6 LTS) machine. The path is a bit different i.e. /usr/local/<blah_blah> and the directory tree looks somewhat like this:
milan#my_machine:/usr/local/<blah_blah>$ tree -L 4
.
├── bin
│   ├── opencv_annotation
│   └── ...
├── include
│   └── opencv4
│   └── opencv2
│   ├── ...
│   ├── core
│   ├── core.hpp
│   ├── ...
│   └── ...
├── lib
│   ├── cmake
│   │   └── opencv4
│   │   ├── OpenCVConfig.cmake
│   │   └── ...
│   ├── ...
│   ├── libopencv_core.so -> libopencv_core.so.4.2
│   ├── libopencv_core.so.4.2 -> libopencv_core.so.4.2.0
│   ├── libopencv_core.so.4.2.0
│   ├── ...
│   ├── ...
│   ├── opencv4
│   │   └── 3rdparty
│   │   ├── ...
│   │   └── ...
│   ├── python2.7
│   │   └── dist-packages
│   │   └── cv2
│   └── python3.6
│   └── dist-packages
│   └── cv2
└── share
├── licenses
│   └── opencv4
│   ├── ...
│   └── ...
└── opencv4
├── ...
│   └── ...
├── ...
└── ...
I had a similar issue for PCL (Point Cloud Library) in the past and my answer/solution fixed that. So, I tried something similar:
In settings.json, I put:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/**"
],
and in the c_cpp_properties.json file, I put:
"includePath": [
"${workspaceFolder}/**",
"${default}"
],
However, doing this is not fixing the issue. C++ IntelliSense/autocomplete still does not work for OpenCV C++. So, how to fix this issue?
Sample Code:
Note1:
In cmake, /usr/local/<blah_blah>/include/opencv4 is used under include_directories.
Compilation and execution work fine.
Note2: the following questions/issues are different from mine:
VSCode autocomplete not working for OpenCV installed from source -- for OpenCV Python, not C++
cv2 (opencv-python) intellisense not working -- for OpenCV Python, not C++
It turned out that in my settings.json file, the includePaths were set like this:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
.
.
],
However, in my code, the headers were included like:
#include <opencv2/core.hpp>
If the opencv2 folder needs to be included in the #include directive, the includePaths should look like this:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4",
.
.
],
So, the following includePaths configuration fixed the issue with IntelliSense/autocompletion for OpenCV:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4",
"/usr/local/<blah_blah>/include/opencv4/**",
],
For a detailed explanation, take a look into the issue (Issue 9900) I created on vscode-cpptools GitHub page, particularly this thread/reply.
Special thanks to vscode-cpptools and vscode-cmake-tools team!

Sample library build fails with meson

I'm following the instructions described in https://mesonbuild.com/IndepthTutorial.html to build a library
Having created the necessary directories and filled with appropriate files. I encounter difficulty when executing "$ meson compile".
The following is a console output of the progress.
[~/tmp/sample_lib_prj]
$ tree --dirsfirst
.
├── include
│   ├── foolib.hpp
│   └── meson.build
├── src
│   ├── meson.build
│   ├── source1.cpp
│   └── source2.cpp
├── test
│   ├── footest.cpp
│   └── meson.build
└── meson.build
[~/tmp/sample_lib_prj]
$ meson builddir && cd builddir
The Meson build system
Version: 0.53.2
Source dir: /home/user/tmp/sample_lib_prj
Build dir: /home/user/tmp/sample_lib_prj/builddir
Build type: native build
Project name: sample_lib_prj
Project version: 0.1
C++ compiler for the host machine: c++ (gcc 9.3.0 "c++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0")
C++ linker for the host machine: c++ ld.bfd 2.34
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /usr/bin/pkg-config (0.29.1)
Run-time dependency glib-2.0 found: YES 2.64.6
Build targets in project: 2
Found ninja-1.10.0 at /usr/bin/ninja
[~/tmp/sample_lib_prj/builddir]
$ tree --dirsfirst
.
├── include
├── meson-info
│   ├── intro-benchmarks.json
│   ├── intro-buildoptions.json
│   ├── intro-buildsystem_files.json
│   ├── intro-dependencies.json
│   ├── intro-installed.json
│   ├── intro-projectinfo.json
│   ├── intro-targets.json
│   ├── intro-tests.json
│   └── meson-info.json
├── meson-logs
│   └── meson-log.txt
├── meson-private
│   ├── build.dat
│   ├── cmd_line.txt
│   ├── coredata.dat
│   ├── foobar.pc
│   ├── install.dat
│   ├── meson_benchmark_setup.dat
│   ├── meson.lock
│   ├── meson_test_setup.dat
│   ├── sanitycheckcpp.cc
│   └── sanitycheckcpp.exe
├── src
├── test
├── build.ninja
└── compile_commands.json
6 directories, 22 files
[~/tmp/sample_lib_prj/builddir]
$ meson compile
ERROR: Neither directory contains a build file meson.build.
With the current version of meson (0.62.1) you can compile your project the way you first tried: going into the build directory and running meson $ cd builddir then $ meson compile.
Alternatively you can compile the project by remaining on the source root directory and run $ meson compile -C builddir. The -C flag is used to specify a directory to cd into before running a command.

Using cmake, how can I link a third_party library to my own program (to find the project, build it from source, and install, link)

How can I do it in a good practice. This is the repo structure:
~/workspace$ tree -L 3
.
├── my_program
│   ├── src
│   │   ├── module1
│   │   ├── module2
│   │   ├── CMakeLists.txt
│   │   └── ...
├── needed_library
│   ├── src
│ │ ├── module3
│ │ ├── module4
│ │ ├── CMakeLists.txt
│ │ ├── README.md
│   │   └── ...
For needed_library, I learned from the README that I can build it manually by:
mkdir build
cd build
cmake ../src
make
make install
And needed library and headers will be installed.
How can I integrate this process into my own program's CMakelists.txt? And link the desired library and header to my program?

Cython / C++ any repos of good example?

Tried googling this morning - and found this
https://gist.github.com/cournape/1077528
But I ran python3 setup.py install - and that's not what I really wanted. I would like to wrap my c++ in python and not install locally.
So I see
├── build
│   ├── lib.linux-x86_64-3.4
│   │   ├── rectangle.cpython-34m.so
│   │   └── rect.cpython-34m.so
│   └── temp.linux-x86_64-3.4
│   ├── rectangle.o
│   ├── Rectangle.o
│   └── rect.o
├── rectangle.c
├── rectangle.cpp
├── Rectangle.cpp
├── Rectangle.h
├── rectangle.pyx
├── rect.cpp
├── rect.pyx
└── setup.py
Now I can use the module because it's installed - but how would I use it if it was compiled in place?