I have just started having a go at developing a small KDE app as a test for myself and I have had some problems fathoming how to use cmake which I have largely overcome. Currently my app builds ok (i.e. cmake && make run without errors). However running 'make install' gives the following error:
kemra102#kaon:~/projects/kquickformat/build> make install
[ 0%] Built target kquickformat_automoc
Scanning dependencies of target kquickformat
[ 50%] Building CXX object src/CMakeFiles/kquickformat.dir/kquickformat_automoc.o
Linking CXX executable kquickformat
[100%] Built target kquickformat
Linking CXX executable CMakeFiles/CMakeRelink.dir/kquickformat
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/kquickformat
CMake Error at src/cmake_install.cmake:38 (FILE):
file INSTALL cannot copy file
"/home/kemra102/projects/kquickformat/build/src/CMakeFiles/CMakeRelink.dir/kquickformat"
to "/usr/local/bin/kquickformat".
Call Stack (most recent call first):
cmake_install.cmake:37 (INCLUDE)
make: *** [install] Error 1
Any ideas as nothing seems obvious to myself?
To install to default locations you usually need root privileges. So either use sudo make install, or rerun cmake specifying an installation prefix where you have write permission. For example, I use:
cmake -DCMAKE_INSTALL_PREFIX=$HOME/install/
If you do that, remember also to set all Qt and KDE related environment variables, otherwise the application you installed will not be working properly or at all. I usually call a shell function that does something like:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/install/lib
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$HOME/install/lib/pkgconfig
export KDEDIR=$HOME/install
export KDEDIRS=$KDEDIR
export XDG_DATA_DIRS=$XDG_DATA_DIRS:$HOME/install
export QT_PLUGIN_PATH=$QT_PLUGIN_PATH:$HOME/install/plugins
Your user account does not (at least, should not) have write access to /usr/local/bin. Try sudo make install.
Related
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 new to cmake and OpenCV.
Is there a way that I can use OpenCV on my machine by just building the source code and not installing them to /usr/local/lib on my machine, i.e. without running make install after building the binaries?
The solution would be to set CMAKE_INSTALL_PREFIX to a specific location:
# in opencv/build
cmake .. -DCMAKE_INSTALL_PREFIX=/home/user/path/to/deps/
cmake --build . --target install
Then, configure your project with the same prefix:
# in your project/build
cmake .. -DCMAKE_PREFIX_PATH=/home/user/path/to/deps/
In your cmake files, simply use find_package(OpenCV)
I generated VTK 8.1.1 VS2015 solution by CMake, and when I build 'ALL_BUILD' project, it works well.
but when I try building 'INSTALL' project, the error followed occurs:
-- Installing: C:/Program Files/VTK/share/doc/vtk-8.1/doxygen/doc_index.stop
2> -- Installing: C:/Program Files/VTK/share/doc/vtk-8.1/doxygen/doc_readme.txt
2> CMake Error at Utilities/Doxygen/cmake_install.cmake:60 (file):
2> file INSTALL cannot find
2> "C:/workspace/VTK_build/Utilities/Doxygen/doc/html".
2> Call Stack (most recent call first):
2> cmake_install.cmake:226 (include)
2>
I do run vs2015 as administrator.
and I have checked that there doesn't have a folder called doc under 'Doxygen' indeed.
please tell me why does this error happen? did I config something wrong?
and what should I do now?
update 1 :
I delete the sentence in file 'cmake_install.cmake' that uses /Doxygen/doc/html.
It is compiled successfully, but I don't know if there would have some thing wrong in the future.
update 2 :
The problem is solved. It just need to build DoxygenDoc separately and /Doxygen/doc/ and some other files will be generated. For more details please see comments below.
The problem is that the documentation has not been build as its target DoxygenDoc is not part off the ALL_BUILD target (which makes sense as you don't want always rebuild the documentation during the development).
Building the documentation creates the required directories and makes it possible to install the documentation.
Note also that the BUILD_DOCUMENTATION in CMake has to be set to be able to build the documentation.
I have a CMake sample project that I would like to build on Jenkins running on Ubuntu 15.10. I have installed:
https://wiki.jenkins-ci.org/display/JENKINS/CMake+Plugin
And created two build steps:
Run CMake to generate makefiles
Run make all from the build dir
It works fine:
[build] $ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug /var/lib/jenkins/workspace/cmake-test/cmake-gtest/src
-- Configuring done
-- Generating done
-- Build files have been written to: /var/lib/jenkins/workspace/cmake-test/cmake-gtest/build
[build] $ /usr/bin/make
[ 4%] Built target libfoo
[ 9%] Built target libbar
[ 14%] Built target myApp
[ 52%] Built target gmock
[ 90%] Built target gtest
[100%] Built target testfoo
[cmake-test] $ /bin/sh -xe /tmp/hudson1792271459427590561.sh
+ cd cmake-gtest/build
+ make all
[ 4%] Built target libfoo
[ 9%] Built target libbar
[ 14%] Built target myApp
[ 52%] Built target gmock
[ 90%] Built target gtest
[100%] Built target testfoo
Finished: SUCCESS
But is this the recommended approach for using CMake in a CI/Jenkins setup?
Currently, my CMake/Jenkins build will on each push; 1) generate the makefiles, 2) build the project.
I am a bit worried that the first step 1) generate makefiles would eat up build time and it does not really seem optimal to do this step on each push. Especially since I would not expect to change CMakeLists.txt files that often, but when they change newly generated files should, of course, be used.
Is the above approach common practices that I just have to get used to or have I missed something?
Yes, you can do it in one step.
For example, in my Jenkins environment, when building the Ubuntu jobs I use the CMake plugin for the whole compilation, as it allows multiple build tool invocations.
My screenshot at the bottom of this post is of a CMake step in a job (I use Ninja instead of Unix Makefiles, but the effect is the same).
I use two build invocations:
Blank - equivalent to calling ninja or make in a shell,
Install - equivalent to calling DESTDIR=. ninja install.
If I wanted to build additional targets from the makefiles, I could just add extra invocations to this step.
Note that in your screenshot you have a blank invocation in the configuration. This will already be calling make, and as confirmed by your log output, you are in fact compiling your project twice, because of your manual call to make all in the following step.
You can remove your shell step and your project will still build.
Regarding your question on best practices and regenerating CMake, I refer you to this article on Jenkins Best Practices where it states:
To ensure a build can be reproducible, the build must be a clean build, which is built fully from Source Code Control. This practice also implies that all code including third-party jars, build scripts, release notes, etc. must be checked into Source Code Control.
Note that I also check "Clean Build" in my CMake step, so that the entire CMake workspace is wiped out and the project is generated from scratch for every build. This ensures there are no issues caused by stale cache variables, etc.
Screenshot of a CMake step in one of my jobs:
I am not even sure you need this plugin. AFAIR the plugin webpage it is only useful if you want Jenkins to use a specific CMake version, or you want a GUI for which CMake variables you might want to set. I just execute CMake from the command line.
For your second part of the question, If you change CMakeLists.txt, the Makefile will automatically rerun CMake, so strictly speaking it is not necessary to run CMake each time. But on the other side, CMake configuring is quite fast and most likely takes less time than compiling.