CMake strange behavior - makefile

After I generated Makefile with CMake I ran in MSYS:
msys>make
It launched cmd.exe within msys and started new make.exe process that did nothing.
It's not a single case - every project that I try to build with CMake leads to this trap.
What's wrong?

MSYS and MinGW makefiles (as CMake understands it) is not the same. In this case I used to generate MSYS makefiles.

If you want to use MinGW compiler, I suggest you use MinGW shell prompt instead of MS cmd.exe. This ensure that several MinGW compiler specific environment variables are correctly set.
Then use "MinGW Makefiles" as generator and mingw32-make as make program.
If you use MSYS you must use "MSYS Makefiles" and the make program should be called simply make (if you have installed it correctly).
If you generate "MinGW Makefiles" and call make, the wrong make program is called. Specify explicitely mingw32-make.

Related

make without makefile after cmake

I try to use the c++ language bindings for the ev3dev lego brick: https://github.com/ddemidov/ev3dev-lang-cpp
The instruction is as follows:
mkdir build
cd build
cmake .. -DEV3DEV_PLATFORM=EV3
make
I am running windows and have cmake and mingw available. After running cmake it creates some files in the build directory. However: There is no makefile which could be picked of by make. So I am wondering how iam supposed to compile these bindings
On Windows, CMake generates a MSVC solution by default. Check for a .sln file in your build directory.
The instructions you linked are assuming a Unix-ish platform, where the default is to create Makefiles.
If you actually want Makefiles on Windows, add -G "Unix Makefiles" to the cmake line.
If you want to use MSVC as compiler but work on the command line, another option is -G "NMake Makefiles", and calling nmake after that.
Make sure to delete your build directory before trying to build a new generator target. CMake can be touchy about that.
Check cmake --help for a list of available options. (Especially the generator targets are platform-specific.)

Understanding roles of CMake, make and GCC

1. cmake is a command from CMake software: preparation for build automation system; make and make install are commands from Make software: build automation system.
2. From reading this post, what I understand is that:
a. This "cmake and make" stuffs actually use g++ / gcc in its implementation. cmake and make stuffs are basically just tools in using g++ / gcc. Is that correct?
b. gcc / g++ are the compiler that do the actual work.
c. So I can just use gcc / g++ directly without using the make and CMake things?
3. According to this stackoverflow answer: CMake takes a CMakeList.txt file, and outputs it to a platform-specific build format, e.g., a Makefile, Visual Studio, etc.
However when I came across this openCV installation :
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
It executes cmake command in a directory where there is no CMakeLists.txt file. Can you explain and elaborate on this?
4. The usual steps that I've seen are: cmake, make, sudo make install.
I read this stackoverflow post, what I understand:
(i) make is for building the project.
(ii) make install is to copy the binary / executables to the installed directories.
a. So when we make, where are the result / binary files / executables stored at?
b. If we only run make without make install, does it mean that the files are not generated?
c. I came across this openCV tutorial on using openCV with GCC and CMake. It uses:
cd <DisplayImage_directory>
cmake .
make
Why doesn't it do make install as well?
5. In summary:
CMake takes CMakeList.txt file (which is cross platform) to generate a Makefile (which is specific to a platform).
I can just write Makefile manually and skip the CMake step. but it is better to do with the CMake step because it is cross platform, otherwise I have to rewrite the Makefile again if I change platform.
Make takes Makefile (which is generated by CMake or written manually) as a guide to compile and build. Make basically uses gcc / g++ or other compiler in its work. Make itself is just a tool for the compiler.
Make install put the result / executables into the install path
CMake generates files for other build systems. These can be Makefiles, Ninja files or projects files for IDEs like Visual Studio or Eclipse. The build files contain calls to compilers like GCC, Clang, or cl.exe. If you have several compilers installed, you can choose one.
All three parts are independent. The compiler, the build system and CMake.
It is easier to understand when you have the history. People used their compiler. Over time they added so many flags, that it was cumbersome to type them every time. So they put the calls in a script. From that the build systems (Make, Ninja) evolved.
The people wanted to support multiple platforms, compilers, scenarios and so on and the build system files became hard to maintain and their use was error-prone. That's the reason people invented meta build system that creates the files for the actual build system. Examples are Autotools or CMake.
Yes
CMake does not use your compiler, make does not implement it, but it calls (uses) the compiler.
The CMakeLists.txt file should be in the parent directory of release. The last argument of the CMake call indicates the path where the CMakeLists.txt file is located.
Right, make generates the file in the build directory. In your example from 3. release is the build directory. You can find all the generated files and use them. Installing is optional, especially if you want to develop the software, you are not installing it.
Try writing Makefiles for a large project and you will see how much work it is. But yes, everything in 5 is right.

Using cmake 3.5.2 installed through MSYS2 under Windows, "MinGW Makefiles" generator is missing

I'm trying an hello world test to make cmake under Windows, using MinGW as compiler.
This answer suggests to run cmake with the -G flag as following:
cmake -G "MinGW Makefiles" .
However, if I do this, I get a message saying that that is not a known generator.
Indeed, running cmake --help, under the Generators section it lists the following generators:
and as you can see, "MinGW Makefiles" is not listed.
If this is relevant, I have MinGW installed and working on my system in the usual folder C:\MinGW. I also have MinGW-w64 installed through WinBuilds and MSYS2, again in the default installation folders.
I'm using cmake version 3.5.2, installed through MSYS2.
Why is "MinGW Makefiles" not listed among the generators?
Only the Windows version of CMake does know the MinGW Makefiles and MSYS Makefiles generators.
If you have downloaded the MinGW/MSYS CMake version try using the Unix Makefiles generator or don't use the -G option (to auto-detect your compiler toolchain).
If you still get errors, please see the references below.
References
cmake MSYS Makefiles generator missing
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found

target_compile_features fails on MinGW-w64 in MSYS2

I recently installed MSYS2 on Windows, along with the MinGW-w64 toolchain and CMake. Specifically, I used the following packages:
mingw-w64-i686-gcc
mingw-w64-i686-cmake
make
Trouble is, whenever I invoke CMake from within the MSYS2 shell with cmake -G"MSYS Makefiles", it fails with the following:
target_compile_features no known features for CXX compiler
"GNU"
version 4.9.2.
The line in CMakeLists.txt that generates the error is this: target_compile_features(myproject PUBLIC cxx_decltype).
If I run CMake from outside the MSYS2 shell (I also have it installed separately) with the "MinGW Makefiles" generator, the makefile generation succeeds.
Inside MSYS2, the CMake version is 3.2.3. The version outside is 3.3.0.
Is there any way to resolve this issue? Thanks in advance.
There was bug about interaction of compile features mechanism in CMake 3.3 with gcc 4.8+:
https://public.kitware.com/Bug/view.php?id=15443. It have been fixed several months ago. You need that fix being applied.
Run cmake from mingw64_shell.bat or mingw32_shell.bat. CMake will otherwise pickup msys2 GCC rather than a native one.

Pass option to cmake for future option to crosscompilation (CROSS_COMPILE)

IF(UNIX)
# CROSS COMPILATION! ON/OFF
#SET(CMAKE_C_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-gcc)
#SET(CMAKE_CXX_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-g++)
#SET(CMAKE_C_COMPILER /home/username/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-gcc)
#SET(CMAKE_CXX_COMPILER /home/username/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-g++)
here is what I do now for cross-compilation. I want to add option to run it alike that:
make CROSS_COMPILE=~/projects/buildroot/output/host/usr/bin/arm-linux-
and if I do not path CROSS_COMPILE to make (not to cmake) it must use system defaults so cmake must path this option to makefile. How can I make it?
Buildroot generates a CMake toolchain file for you. Depending on your Buildroot, it might be directly in the output directory, or in output/host/usr/share/buildroot. The file is named toolchainfile.cmake. Then to build your CMake applications, do:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/buildroot/output/host/usr/share/buildroot/toolchainfile.cmake
This file contains all the definitions of the cross-compiler paths, pkg-config environment variables, headers and libraries location, etc.
For the simplest method, do this:
SET(CMAKE_C_COMPILER $(CROSS_COMPILE)gcc)
SET(CMAKE_CXX_COMPILER $(CROSS_COMPILE)g++)
When the CROSS_COMPILE variable is passed to make, it will be substituted with the cross compiler path.
Now, the proper way. Ideally, the CROSS_COMPILE variable should be defined when CMake is run as it is meant to be cross-platform. Using the first solution could break if other CMake generators are used.
This can be done as:
IF(UNIX)
SET(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
SET(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
Then define the variable:
cmake -G "Unix Makefiles" -DCROSS_COMPILE=~/projects/buildroot/output/host/usr/bin/arm-linux-
In this case, CMake will generate proper build files, based on whether CROSS_COMPILE is defined or not.

Resources