What is exactly the command line (process and arguments) used by CLion when invoking CMake? I'm trying to use the same directory for manual builds using the terminal and for building using the IDE, but it seems that one is interacting badly with the other.
I have no problem with using CLion only to handle CMake configurations (to avoid slight configuration mismatch triggering another CMake execution), but it seems that even standard builds using make on the command line trigger cmake again.
I've seen that CLion prints it's "call" to CMake, but I don't see where it references the current working directory. And since on the GUI you configure paths relative to the project root folder (where CMakeLists.txt live), instead of relative to the build folder. I was hoping that this detail is the culprit here.
Usually in the command line I'd do it like this:
$ cd project
$ mkdir -p builds/debug
$ cd builds/debug
$ cmake $MY_CMAKE_OPTS -DSPECIAL_FILE=../../file.ext ../..
On CLion, though, I have to configure it like this:
CMake options: $MY_CMAKE_OPTS -DSPECIAL_FILE=file.ext
Generation path: builds/debug
The rest I've used the default
This special file is used on the configuration phase, so using paths other than relative to project root or absolute paths won't work.
Configuration step command line is shown in CMake view when you load/reload a CMake project: View - Tool Windows - CMake. The view has no default hotkey.
Example: /Users/vic/bin/cmake_ninja_wrapper.py -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" /Users/user/src/helloworld.
Depending on configuration, the current directory can be PROJECT_SOURCE_DIR/cmake-build-debug (where the build files were generated for me), PROJECT_SOURCE_DIR/cmake-build-release, or other.
Build step command line is shown in Messages - Build view. It opens when you invoke build from Build menu. I don't think the current directory matters for it, as all the build files are already generated.
Example: /Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/user/src/helloworld/cmake-build-debug --target helloworld -- -j 6
Then the view can be opened with Cmd-0 on Mac, or through menu: View -
Tool Windows - Messages.
To work with relative paths, you can refer to PROJECT_SOURCE_DIR variable in your CMakeLists.txt.
Related
Visual Studio 2022 CMake project
I build a qt cmake project in vs2022, everything works well, but when last step to run exe, it says the error of lack of dll files. I know that this is the problem of dll file directory. I can add it to system env path, or copy dll to exe file dir, but I guess that additional way that not mucks system env exists. I notice that VS traditional project can set debugger env in property, which set a local env variable, but I cannot find the way to set this in new support CMake Project in VS2022.
The IDE QtCreator also provide an analogous way that set env var for only project to run exe file, so any way to set this in VS like the traditional sln project, I search and find that some configure json file may help, but I cann't find precise setting.
As above, I guess some ways exist to set exe runtime env var to find dll file in VS CMake project, anyone could give me any tip, any helpful advice would be highly appreciated!
Finally, I found the way for cmake project without solutions in visual studio,
find launch.vs.json file by this
add custom env variable path to json file
add following content to project in configurations key:
"env": {
"PATH": "<dll-file-path>"
}
It works well for me, hope this can help you.
You can add the following properties to your CMakeLists.txt file that contains the executable target:
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT <your_executable_target_name>)
set_property(TARGET <your_executable_target_name> PROPERTY VS_DEBUGGER_ENVIRONMENT "PATH=${QTDIR}/bin")
If you need a build system independent solution, adding a custom target that simply launches the program could be an option:
Helper script (run_program.cmake)
set(ENV{PATH} "${PATH}")
execute_process(COMMAND "${PROGRAM}")
Actual project
add_executable(MyProgram ...)
add_custom_target(RunMyProgram COMMAND ${CMAKE_COMMAND} -D "PROGRAM=$<TARGET_FILE:MyProgram>" -D "PATH=${QT_BINARY_DIR};$ENV{PATH}" -P ${CMAKE_CURRENT_SOURCE_DIR}/run_program.cmake)
This allows you to use e.g.
cmake --build build_dir --target RunMyProgram --config Release
after building to run the program with the modified PATH environment variable.
Another option would be to use add_test + ctest, to run the program with a modifier environment, but this could easily render real test cases unuseable.
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.)
For a project which uses MQTT, I always had to compile the QtMqtt module from source, because it wasn't included in the prebuilt windows release and couldn't be chosen for installation either. In Qt5 that was pretty easy: Download source code from official git (https://code.qt.io/cgit/qt/qtmqtt.git/), open the .pro file in QtCreator and compile the project. For installation, I just moved the .dll files to my Qt install directory.
Now in Qt6, the build process was switched from qmake to cmake, so I cannot simply load the project in QtCreator, but have to compile it manually using CMake, which I find really unintuitive and prone to errors. From what I understand, I cannot compile single modules on their own from now on, but have to get the whole Qt 6.2.0 source code instead (i.e. via installer option) and then use a --target option on CMake to build only specific module. So here is what I did so far:
Get Qt source code from installer (installed to Qt/6.2.0/Src)
Create a command line environment according to this manual
Open cmd environment, navigate to build folder (i.e. Qt/6.2.0/build)
Configure build using command: ..\Src\configure -prefix Qt\6.2.0\build
Build with cmake using command cmake --build . --target qtmqtt
Install using command cmake --install .
What happens, is that the configuration works, and the build supposedly too, but installation fails with something like:
CMake Error at qtbase/src/3rdparty/libpng/cmake_install.cmake:41 (file):
file INSTALL cannot find
"F:/DEV/prog/Qt/6.2.0/build/qtbase/mkspecs/modules/qt_ext_libpng.pri": File
exists.
Call Stack (most recent call first):
qtbase/src/3rdparty/cmake_install.cmake:42 (include)
qtbase/src/cmake_install.cmake:42 (include)
qtbase/cmake_install.cmake:244 (include)
cmake_install.cmake:42 (include)
The folder Qt/6.2.0/build then only consists of .cmake files but nothing which seems to be usable .dll files for me. I just don't understand how to properly set up everything with cmake. Why would they make it so complicated after all now, as it was fairly easy to compile modules with qmake in Qt5?
Having Qt 6.4.2 installed in ${HOME}/Qt/6.4.2/ using the Qt Installer, this is how I did it on Linux.
Detailed steps:
# Create a work directory
mkdir ~/temporal && cd ~/temporal
# Clone the repository
git clone https://github.com/qt/qtmqtt.git
# Switch to the repository
cd qtmqtt
# Checkout the branch corresponding to the target kit
git checkout 6.4.2
# Create a directory to build the module cleanly
mkdir build && cd build
# Use the qt-configure-module tool
~/Qt/6.4.2/gcc_64/bin/qt-configure-module ..
# Build it here
~/Qt/Tools/CMake/bin/cmake --build .
# Install the module in the correct location
~/Qt/Tools/CMake/bin/cmake --install . --verbose
Testing on a clean project:
Edit the project's CMakeLists.txt file
(1) Add Mqtt to the relevant find_package macro like this:
find_package(QT NAMES Qt6 COMPONENTS Widgets Network Sql Mqtt REQUIRED)
(2) Add Qt${QT_VERSION_MAJOR}::Mqtt to a target_link_libraries line like this:
target_link_libraries(MyCleanProject PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Mqtt Qt${QT_VERSION_MAJOR}::Sql)
(3) Run CMake
Try actually using the module
Add relevant includes in the project source like this:
#include <QtMqtt/QtMqtt>
// and then try to use QtMqtt classes
QMqttClient client;
Rebuild the project. Should compile and link cleanly.
Addendum
It's desirable to have proper environment variables set while building Qt projects from the CLI. My preference is to have a script in my user directory with all the relevant variables.
My Qt_environment.sh:
export QT_VERSION="6.4.2"
export QT_INSTALL_DIR="${HOME}/Qt"
export CMAKE_BIN_DIR="${QT_INSTALL_DIR}/Tools/CMake/bin"
export QMAKE_BIN_DIR="${QT_INSTALL_DIR}/${QT_VERSION}/gcc_64/bin"
export CMAKE_PREFIX_PATH="${QT_INSTALL_DIR}/${QT_VERSION}/gcc_64/"
export NINJA_DIR="${QT_INSTALL_DIR}/Tools/Ninja"
export PATH="${PATH}:${CMAKE_BIN_DIR}:${QMAKE_BIN_DIR}:${NINJA_DIR}"
One can choose to load manually from the command line before building a project like this
source $HOME/Qt_environment.sh
# do some Qt stuff here, cmake, ninja, etc
or simply have it loaded from .bashrc for every new bash shell. The same can be accomplished for any other shell.
# $HOME/.bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# ...
# rest of the .bashrc file ommited for brevity
# ...
# Relevant part here - add these two lines at the end
# Load Qt environment variables
source "$HOME/Qt_environment.sh"
From what I understand, I cannot compile single modules on their own
from now on, but have to get the whole Qt 6.2.0 source code instead
(i.e. via installer option)
That's not correct. Given a pre-built Qt, you should be still able to just build the qmqtt package from source by running e.g.
<QTDIR>\bin\qt-configure-module <mqtt_src_dir>
cmake --build .
try to replace cmake --install . with cmake --install qtmqtt
I am trying to use CMake in order to compile opencv.
I am reading the tutorial but can't understand what is CMakeLists files and how is it connected to the gui of CMake?
Also couldn't understand what are makefiles, are they the same is CMakeLists?
And which file is it which I in the end open with visual-studio?
I don't know about Windows (never used it), but on a Linux system you just have to create a build directory (in the top source directory)
mkdir build-dir
go inside it
cd build-dir
then run cmake and point to the parent directory
cmake ..
and finally run make
make
Notice that make and cmake are different programs. cmake is a Makefile generator, and the make utility is governed by a Makefile textual file. See cmake & make wikipedia pages.
NB: On Windows, cmake might operate so could need to be used differently. You'll need to read the documentation (like I did for Linux)
CMake takes a CMakeList file, and outputs it to a platform-specific build format, e.g. a Makefile, Visual Studio, etc.
You run CMake on the CMakeList first. If you're on Visual Studio, you can then load the output project/solution.
Yes, cmake and make are different programs. cmake is (on Linux) a Makefile generator (and Makefile-s are the files driving the make utility). There are other Makefile generators (in particular configure and autoconf etc...). And you can find other build automation programs (e.g. ninja).
CMake (Cross platform make) is a build system generator. It doesn't build your source, instead, generates what a build system needs: the build scripts. Doing so you don't need to write or maintain platform specific build files. CMake uses relatively high level CMake language which usually written in CMakeLists.txt files. Your general workflow when consuming third party libraries usually boils down the following commands:
cmake -S thelibrary -B build
cmake --build build
cmake --install build
The first line known as configuration step, this generates the build files on your system. -S(ource) is the library source, and -B(uild) folder. CMake falls back to generate build according to your system. it will be MSBuild on Windows, GNU Makefiles on Linux. You can specify the build using -G(enerator) paramater, like:
cmake -G Ninja -S libSource -B build
end of the this step, generates build scripts, like Makefile, *.sln files etc. on build directory.
The second line invokes the actual build command, it's like invoking make on the build folder.
The third line install the library. If you're on Windows, you can quickly open generated project by, cmake --open build.
Now you can use the installed library on your project with configured by CMake, writing your own CMakeLists.txt file. To do so, you'll need to create a your target and find the package you installed using find_package command, which will export the library target names, and link them against your own target.
Cmake from Windows terminal:
mkdir build
cd build/
cmake ..
cmake --build . --config Release
./Release/main.exe
Regarding CMake 3.13.3, platform Windows, and IDE Visual Studio 2017, I suggest this guide. In brief I suggest:
1. Download cmake > unzip it > execute it.
2. As example download GLFW > unzip it > create inside folder Build.
3. In cmake Browse "Source" > Browse "Build" > Configure and Generate.
4. In Visual Studio 2017 Build your Solution.
5. Get the binaries.
Regards.
My need is simple. I have to compile and use googletest on windows using MinGW with msys. Has anyone some experience doing this?
Thanks for answers.
It took me some time but I figured it out. Here is the guide for anyone who face the same problem.
To be able to compile GoogleTest on Windows follow this instructions:
I assume you have MinGW with MSYS istalled.
Download and install CMake from the official site http://www.cmake.org/. Use the Win32 installer
version. Once you have completed the installation process copy executable files from
"xxx/CMake/bin" to "xxx/MinWG/bin".
Download and install Python from http://www.python.org/. Again, the Windows installer does the job
fine.
Once you have completed the installation process copy the "python.exe"
form python folder to
"xxx/MinWG/bin".
Download the latest stable GoogleTest from http://code.google.com/p/googletest/ and unpack it into some folder.
Run MSYS terminal and execute following commands.
cd xxx/gtest-x.x.x
cmake -G "MSYS Makefiles"
make
If you have compilation errors from pthread follow these instructions.
Copy the include folder "xxx/gtest-x.x.x/include" into your MinGW gcc include.
Copy the library files "xxx/gtest-x.x.x/*.a" into your MinGW gcc lib.
When you compile tests add "-lgtest" parameter to gcc.
EDIT
Commentators are right. The coping of executables worked for me but generaly it is not a good practice. Try to use a symbolic link instead.
To build libgtest.a without cmake/python, but only using mingw make, gtest now has a 'make' folder with a plain old makefile in it.
Make sure, mingw\bin is in the path (try running 'g++' or something).
Enter the gtest 'googletest\make' folder and run 'make'.
To test, run 'sample1_unittest' (gtest sample test output should appear).
To generate the library 'libgtest.a', run 'ar -rv libgtest.a gtest-all.o'
The library created is a full static library with no dll's generated.
That should be all.
By the way, this also works for building googlemock, just enter the googlemock folder instead of googletest, and follow the same procedure.
The question was asked in 2011 and answer with most votes is also answered the same year. So, a fresh answer would improve the question effectiveness.
Tools You need & I tested with:
Mingw64 8.0.2
GoogleTest GitHUb Source Code repo branch 1.10.0
CMake 3.20.4
and Windows10
Steps
Install the mingw64 by double clicking and chose the path which does
not have space between directory names e.g. "Program Files"
Open settings of the windows and then search environment variables
and oepn the dialog box to edit the Path environment variable
Add the mingw64/bin directory name in the Windows Path Environment
variable e.g. C:\Users[USERNAME]\mingw64\bin (replace [USERNAME]
with your username e.g. Michael or Lee etc)
Install CMake. It is double click install procedure. Make sure, its
bin directory path is added in the Path Environment Variable.
It would be installed in C:/Program Files/...
Download GoogleTest repo extract it and create a build directory
inside the extracted directory.
Execute the following commands
$ cd build
$ cmake .. -G "MinGW Makefiles"
$ mingw32-make.exe
Copy the four static libraries(*.a) from build directory
[ex: C:\Users[USERNAME]\sourcecodes\googletest-master\build\lib]
into lib of MingW64
[ex: C:\Users[USERNAME]\mingw64\x86_64-w64-mingw32\lib]
Go to the GoogleTest extracted repo, navigate to
[ex
C:\Users[USERNAME]\sourcecodes\googletest-master\googletest\include\gtest]
Copy that whole gtest directory and copy to the folder
C:\Users[USERNAME]\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include
You are done to go. You can build and link Googltest with your C++ project. I also paste a CMakelists.txt sample
cmake_minimum_required(VERSION 3.12)
project(ProjectName VERSION 1.0.0 LANGUAGES CXX)
include_directories(include)
set(SOURCES src/library.cpp include/library.h)
add_executable(libabc ${SOURCES})
#############
## Testing ##
#############
enable_testing()
find_library(GTest gtest)
add_executable (unitTest test/unit_test.cpp)
target_link_libraries (unitTest gtest gtest_main)
add_test(AllFactTest unitTest)
I hope it would work.
From the README of https://github.com/google/googletest/tree/master/googletest
:
When building Google Test as a standalone project, the typical workflow starts
with:
mkdir mybuild # Create a directory to hold the build output.
cd mybuild
cmake ${GTEST_DIR} # Generate native build scripts.
If you want to build Google Test's samples, you should replace the last command
with
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
As alternative it is also possible to build googletest using the usual MSYS/Mingw make.
So here is my alternative way:
Make sure MSys/MingW is installed on your Windows and the PATH environment is set to it
Open a cmd window - you can set the PATH explicitly here as well
CD to the unzipped googletest directory
Call configure with sh (part of MSys): sh configure
Call make -> libgtest.a should be built. It is placed in your googletest-directory lib/.libs subdirectory
See README of googletest of how to integrate the libgtest.a to your system. Also see googletest primer in the googletest wiki of how to compile. Alternatively specify the library path for gcc -L<googleTestDir>/lib/.libs and add -lgtest to link with your test project executable.
When using ASSERT_DEATH macro to check for asserts in your tested code (meaning asserts in your lib or application, not in googletest), call SetErrorMode - example main:
#include <windows.h>
#include "gtest/gtest.h"
int main (int argc, char** argv)
{
// this prevents annoying error message boxes popping up
// when assert is called in your program code
SetErrorMode(SEM_NOGPFAULTERRORBOX);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
You don't need to copy the binaries as long as you have them in your path. Install python and CMake. Test them in your msys (MinGW console)
which cmake
which python
If you see the path, then you have the binaries. If not, add their path to your Environmental Variables>PATH or just update within msys (update installation paths if necessary)
export PATH=$PATH:/c/Program Files (x86)/CMake/bin/cmake.exe:/c/Python27/python.exe
Then you can build as suggested:
cd xxx/gtest-x.x.x
cmake -G "MSYS Makefiles"
make
Test if everything works:
cd make
make
./sample1_unittest.exe
With MSYS2, simply install the mingw-w64-x86_64-gtest package:
pacman -S mingw-w64-x86_64-gtest
Then compile tests with the flags -lgtest -lgtest_main.