cmake --build vs make, what the difference? - c++

After
cd build
cmake -B . -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake -S ..
Looks like
cmake --build .
and
make
do the same here on macOS.
So, when should I use one or the other?

For a simple use there is not much difference, except that cmake --build is more generic and works with any generator. So today you use make, tomorrow ninja or msbuild and CMake handles it with simple cmake --build which you can put in a script or readme.
But since the inception of presets these 2 methods started to really diverge. You can add some things in the build part of your preset which then can be invoked by cmake --build --preset MyPreset while you can't do the same with simple make.
So since you are using CMake as your project tool I'd recommend to start using its interface for the build since that's how it will be meant to use in the future anyway (at least it seems so).

make is not a recognized command in Windows. In times like this, cmake --build . is your friend.
cmake build . also works, sometimes and I don't know the deeper explanations of these phenomena.

cmake -B ...typehere
type - build type
e.g .sln projects for vs studio
make - build your project
cmake - allows you to create a different build types for your project.

Related

How to install a cpp library using cmake on Windows x64?

I'm using CLion with MinGW-GCC on the Windows-x64 platform - This is the background of the problem.
I was trying to install gtest before. But a lot of confusion arose in the middle.
First time I ran those commands(in googletest-release-1.12.1\) according to the instructions of googletest-release-1.12.1\googletest\README.md:
mkdir build
cd build
cmake ..
But I got error messages like:
CMake Error at CMakeLists.txt:51 (project):
Failed to run MSBuild command:
C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe
to get the value of VCTargetsPath:
Then I changed my last command to
cmake -G "MinGW Makefiles" ..
because I use make provided by MinGW. I don't know whether it's right but, it ran properly.
then I called
make
make install
make ran smoothly. But when I ran make install, I got these messages:
Install the project...
-- Install configuration: ""
-- Installing: C:/Program Files (x86)/googletest-distribution/include
CMake Error at googlemock/cmake_install.cmake:41 (file):
file INSTALL cannot make directory "C:/Program Files
(x86)/googletest-distribution/include": No such file or directory.
Call Stack (most recent call first):
cmake_install.cmake:42 (include)
make: *** [Makefile:109: install] Error 1
I have no idea at all this time. So I changed my way. According to this answer, I copied the whole library into my project and edited CMakeLists.txt like this:
cmake_minimum_required(VERSION 3.23)
project(gtest_study)
set(CMAKE_CXX_STANDARD 20)
add_subdirectory(googletest-release-1.12.1)
include_directories(googletest-release-1.12.1/googletest/include)
include_directories(googletest-release-1.12.1/googlemock/include)
add_executable(gtest_study main.cpp)
target_link_libraries(gtest_study gtest gtest_main)
target_link_libraries(gtest_study gmock gmock_main)
So my questions are:
Is there any difference between the two which build it using make and cmake metioned firstly, and just use commands like include_directories and target_link_libraries in CMakeLists.txt? (maybe like .h and .dll file? Or just completely the same? I don't know)
When I use make install to install a library on Windows, what should I do in particular? Specify some directory (I don't know which one) or what?
Although in my system environment I use MinGW-makefile, in CLion which the libraries are eventually used, I use ninja as the generator for CMake (it just comes with CLion, not installed for the system). Do I have to specify it and how? (-G "Ninja"doesn't work in my native env)
The difference between
cmake ..
and
cmake -G "MinGW Makefiles" ..
Is the choice of generator: The former uses the default generator, the latter uses the generator you specified. (cmake --help should put a * next to the default generator.)
Based on the error message I assume this is a visual studio generator and you may not be able to run that one properly from within a MinGW terminal.
In the latter case the default install directory seems to be based on the target OS (Windows) but does not seem to incorporate the fact that you're running from a MinGW terminal where the default install path (C:/Program Files (x86)/googletest-distribution) is not valid.
You could try to fix this by providing it during cmake configuration (passing -D 'CMAKE_INSTALL_PREFIX=/c/Program Files (x86)/googletest-distribution' before the source dir) or by providing the install directory during the installation.
The following process should allow you to install the lib. I'm using my preferred way of building here, i.e. not using build system dependent commands, but using cmake to run the build/install commands. I assume the working directory to be the root directory of the gtest sources:
cmake -G "MinGW Makefiles" -S . -B build
cmake --build build
cmake --install build --prefix '/c/Program Files (x86)/googletest-distribution'
The last command needs to be run with admin privileges, the first 2 I don't recommend running as admin. You could instead install to a directory where you do have the permissions to create directories even without admin privileges.
The difference between using the process described above and using add_subdirectory is that the former results in a installation on the system which can be used via find_package and the google test libs won't be rebuilt for every project where you do this.
...
project(gtest_study)
...
# you may need to pass the install location via -D CMAKE_PREFIX_PATH=<install_location> during configuration for this to work
find_package(GTest REQUIRED)
target_link_libraries(gtest_study PRIVATE GTest::gtest_main GTest::gmock)
The latter builds the google test project as part of your own project build and for every project where you use this approach a seperate version of the google test libs is built. Note: there should be no need to specify the include dirs yourself, since this kind of information is attached to the cmake target and gets applied to the linking target automatically:
#include_directories(googletest-release-1.12.1/googletest/include)
#include_directories(googletest-release-1.12.1/googlemock/include)
add_executable(gtest_study main.cpp)
target_link_libraries(gtest_study PRIVATE gtest_main gmock)
As for 3.: The CMake generator used for building GTest should be independent of the generator of the project using it. The thing that's important is that the compilers used by the build systems are compatible. I cannot go into detail about this, since I've never used CLion and therefore have too little knowlege about the compilers used by it. (Personally I'm working with Visual Studio on Windows.)

LLVM build only selected tools or targets

I am new to c++ & am referring to the llvm project https://llvm.org/docs/GettingStarted.html. There is a guide saying
If you are space-constrained, you can build only selected tools or only selected targets. The Release build requires considerably less space.
But I am unable to find the exact way to do it.
Currently, I am running the following to build all the tools
mkdir build
cmake ../llvm
make
This would create many tools such as llvm-addr2line, llvm-ar, llvm-dwarfdump etc.
How could I build it such that it only gives me 1 tool, eg llvm-dwarfdump (eg https://llvm.org/docs/CommandGuide/llvm-dwarfdump.html)?
Is there an easy way to know the code that makes up these command.
Thank you
CMake generates a target for every add_library, add_executable, and add_custom_target command. These targets can be built separately by calling make <target> or with the build tool independent CMake abstraction cmake --build <builddir> --target <targetname> --config Release. To find out which targets have been defined by LLVM you need to inspect all CMakeLists.txt and *.cmake files.

How to build a project generated by CMake for MinGW makefiles?

I'm trying to build SFML's source code after I've ran the directory through CMake and after CMake generated the makefiles. I have no idea how though.
This is how the directory where I've set CMake to dump it's generation to:
On Linux I use
cmake --build .
to build my project. It calls the according build command. It works with make and ninja. Probably it works on Windows with MinGW.
Remember that cmake doesn't come with a build system. It only calls the commands. You have to install the build system you want to use.

Automate CMake build using C++ script

I would like to automate the build of CMake using an MSVC C++ script instead of using CMake-gui to generate the build or CMake terminal or using the CMake integrated on MSVC 2017 by right click on the CMakeLists.txt to build it manually. Assume we have a project (name it: initialize) that includes the CMakeLists.txt and initialize.cpp, so my question is how I can convert these commands into a C++ code, assume build_initialize.cpp:
mkdir build
cd build/
cmake ..
So, the requirement of this tiny C++ code is to
Set the path to this project
Create build folder
Run CMake
At the end if I execute build_initialize.exe, the job is just to build the initialize.cpp using CMake. The goal is to test if the build is success or not as a test case within another project that has several test cases.
You may ask, why I didnot include it to the top CMakelists.txt, and then build it from the beginning using CMake. If I am going to do that, I will get an executable file. As a result, by running the ctest of CMake, the initialize.exe will require a pace of hardware. This is not the goal. My goal is just to build it. If I run build_initialize.exe, just repeat the build using CMake without initialize.exe execution.
Sorry, it could be very simple, but I lack the good experience either in C++ or CMake. Two days have been lost without success.
Thanks to all of you for the comments. The answer has been given by #Fred. To run cmake from C++ script, simply the system() can be used such as: System(cmake -S path_to_src -B path_to_bld).
Useful link: https://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284392&answer=1044654269

How do I see the commands issued by cmake with --build option

How could I see the commands issued when I run "cmake --build . --target INSTALL" command? There doesn't seem to be an option like --versbose or something. The cmake help says that "cmake --build" is an interface to the underlying build tool, but doesn't say anything about the dump of commands issued.
The reason I need this is because, when I try to run msbuild on commandline, it fails with an error saying the target INSTALL doesn't exist in the project. However, cmake succeeds. So, I guess, cmake also might be using msbuild itself, albeit with some specific options.
You can pass additional options to the native build tool with the -- switch, i.e.:
cmake --build . --target INSTALL -- /verbosity:detailed
you can found the solution at:
https://cmake.org/Wiki/CMake_FAQ
On Windows (nmake) you can override CMAKE_VERBOSE_MAKEFILE by using
nmake /S
If you actually want to see what the command looks like, set CMAKE_START_TEMP_FILE and CMAKE_END_TEMP_FILE to "" -- be warned, however, you cannot set these as variables on the CMake command line with -D. Instead, see the very bottom of the file "Modules/Platform/Windows.cmake" and uncomment the lines that set these variables to the empty string.