I have the following trivial CMakeLists.txt (FreeBSD 9.1, CMake 2.8.11.2):
project(temp_proj CXX)
message(${CMAKE_BINARY_DIR})
message(${CMAKE_SOURCE_DIR})
This file is located in /root/trunk/temp. Since I want to perform an out-of-source build, I create a sibling directory temp2 and invoke cmake from there:
root#:/root/trunk # mkdir temp2
root#:/root/trunk # cd temp2
root#:/root/trunk/temp2 # cmake ../temp
/root/trunk/temp
/root/trunk/temp
-- Configuring done
-- Generating done
-- Build files have been written to: /root/trunk/temp
How comes CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR are the same?
What am I doing wrong?
As #Fraser suggested, the issue occurred because of CMakeCache.txt file, which was left in /root/trunk/temp.
Related
I'm using CMake v3.21.0 to invoke Qt's windeployqt during the install stage by the means of the install(CODE) command as follows:
install(
CODE "
execute_process(
COMMAND \"${CMAKE_COMMAND}\" -E
env PATH=\"${windeployqt_ROOT_DIR}\"
\"${windeployqt_EXECUTABLE}\"
# TODO(2021-08-25 by wolters): This is a different path when CPack is`
# used. How to check for this case and obtain the correct output path?
--dir \"${CMAKE_INSTALL_PREFIX}/${args_INSTALL_SUFFIX}\"
--no-quick-import
--no-system-d3d-compiler
--no-virtualkeyboard
--no-compiler-runtime
--no-webkit2
--no-angle
--no-opengl-sw
--verbose 0
\"\$<TARGET_FILE:${args_TARGET}>\"
)
"
COMPONENT runtime
)
This works fine if installing the project:
cmake --build . --config RelWithDebInfo --target install
But when creating a CPack package the files created by windeployqt are not part of the package (ZIP in this case):
cpack -G ZIP -C RelWithDebInfo -D CPACK_COMPONENTS_ALL="runtime"
I know that the issue is the usage of ${CMAKE_INSTALL_PREFIX} in the CODE.
For the install target this is correct.
For the package target this is not correct. Instead the build directory for the current CPack generator should be used, e.g. ${CMAKE_CURRENT_BINARY_DIR}/_CPack_Packages/win64/ZIP/${CPACK_PACKAGE_FILE_NAME}.
My questions are:
Is there a way to differentiate between install and package target in the CODE section? (pseudo-code: if(CMAKE_IS_PACKAGING))
If there is a way: Is it possible to obtain or dynamically build the directory path to the actual CPack temporary "install" directory?
If both problems can be solved the files generated by windeployqt should be part of the packages generated by CPack.
The variable CMAKE_INSTALL_PREFIX should not be expanded in the CMakeLists.txt, as you are doing. Its actual value at invocation time is available inside the install(CODE) fragments.
Consider the following snippet:
cmake_minimum_required(VERSION 3.21)
project(test NONE)
install(CODE [[message(STATUS "HERE: ${CMAKE_INSTALL_PREFIX}")]])
Note that [[ ... ]] escapes variable expansions (you could also use backslashes). Now if you configure this project with -DCMAKE_INSTALL_PREFIX=/tmp/install, you'll see the message print as you expect.
$ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/tmp/install
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --target install
[0/1] Install the project...
-- Install configuration: ""
-- HERE: /tmp/install
If you now run the install script again without reconfiguring or rebuilding, it will still work:
$ cmake --install build/ --prefix /tmp/other-prefix
-- Install configuration: ""
-- HERE: /tmp/other-prefix
This is how CPack runs your install rules. It does not use the configuration-time value of CMAKE_INSTALL_PREFIX. It expects your project to be relocatable (i.e. bug-free).
I'm using cmake to generate a VS2017 solution (and projects...), I try to generate everything in a different folder.
I used both the command line and different variables, but no way, it generate in the "source" folder !
Here are some examples of what I tried:
cd source
cmake -B../build ...
cd build
cmake ../source
cmake --build "../build"
cmake -Dxxx=../build
Any idea ? all theses solutions are expected to generate in the build folder !
Once you have performed in-source build (in source directory), it is impossible to build the project out-of-source: every such attempt will modify in-source build.
You need to clear build files (CMakeCache.txt, probably some other ones) in source directory before using out-of-source builds.
I fixed with:
cd VSBuild
cmake ../
instead of
cd VSBuild
cmake ..
Have you tried this? This will put all the build files under "out"
$ cmake -H. -Bout
To execute:
$ cmake --build out
Describe difference between these two command lines:
C:\xxxxx> cmake -help
Usage
$ cmake [options] <path-to-source>
$ cmake [options] <path-to-existing-build>
Specify a source directory to (re-)generate a build system for it in the
current working directory. Specify an existing build directory to
re-generate its build system.
The last description does not give me how to use the first, or the second.
Could you explain it to me?
When you use you do an in-tree build (cmake .), there is no difference.
When you do an out-of-tree build, there is a difference.
Suppose your project lives in ~/foo and your current directory is ~/foo/build
You have to run cmake .. for the first build. But for subsequent reconfigures, you can use cmake . because there is already a build there.
This command:
cmake [options] <path>
works as follows:
if <path> is not a valid (that is, already configured) CMake build directory, it is assumed to contain a CMakeList.txt. CMake will configure the current working directory as a build directory using <path>/CMakeLists.txt for source directory.
if <path> is a valid CMake build directory, the command reconfigures that directory using the source directory assigned when you first configured that build directory
So the common usage patterns are:
initial configuration:
mkdir my-build-dir
cd my-build-dir
cmake [options] my-source-dir
subsequent (re)configurations:
cmake [options] my-build-dir # current-work-dir is not important
alternative (initial) configuration using undocumented options:
cmake -Hmy-source-dir -Bmy-build-dir [options] # cwd is not important
I would like to rename the installer file that CPack (v2.8.7) produces to include a version number that is obtained at build time from the version control system. It appears this cannot be be done by setting the CPACK_* variables because that happens at "cmake" time.
What I want to be able to do is to run "(n)make package" and have the installer file be created with no further commands required. The two possible approaches that I am aware of are manipulating the CPack filename variables at build time and renaming the final output of CPack.
If using "include(CPack)" in a CMakeLists.txt file then it appears that CPack always runs last and you can't have a post-build command. This mailing list message suggests that a custom target can be written to run CPack, but I was unable to figure out how to do that without creating infinite recursion.
How can this be done?
Why not extract the build-info from the VCS at cmake-time? Then you can easily modify the CPACK_PACKAGE_FILE_NAME to include your version-number.
Added bonus: When doing this at CMake-time, you can e.g. fill a "Readme.txt" file with the git-info using CMake's configure_file and add it to your package. Or perhaps use it to fill a "config.h", which is used in your builds.
Example:
in one of my own projects, I have a little piece of CMake code which finds Git and extracts the current changeset hash from the source code repository. It may not be the best Git way of extracting the info, but it works for me...
# First try to find the git-executable
find_program( Git_EXECUTABLE NAMES git git.cmd PATHS
${Git_DIR}
ENV PATHS
$ENV{Git_DIR}
)
# Run "git log -n 1 --pretty="%h" for the current commit-hash
execute_process( COMMAND ${Git_EXECUTABLE} "log" "-n" "1" "--pretty=\"%h\""
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Hash
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# and use a regex to strip quotes.
string( REGEX REPLACE "^\"(.*)\"$" "\\1" Git_Commit_Hash ${Git_Commit_Hash} )
The result will be a Git_Commit_Hash variable with the 7-char hash value, which is used when setting up CPack:
set( CPACK_PACKAGE_NAME "MyProject" )
message( STATUS " CPack options: " ${CPACK_PACKAGE_NAME} )
message( STATUS " Preparing CPACK: " )
message( STATUS " and hash: ${Git_Commit_Hash}" )
set( CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${Git_Build_Version}_${CPACK_PACKAGE_VERSION}" )
With a bit of help from the CMake mailing list I figured out how to do it, using subversion.
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(myapp)
add_executable(main main.cpp)
install(TARGETS main DESTINATION .)
add_custom_target(first ALL
# update the working copy
COMMAND ${Subversion_SVN_EXECUTABLE} update ${CMAKE_SOURCE_DIR}
# generate cpackoptions.cmake at build time so we get the
# most recent revision number
COMMAND ${CMAKE_COMMAND}
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-DBINARY_DIR=${CMAKE_BINARY_DIR}
-Dproj_name=${CMAKE_PROJECT_NAME}
-P ${CMAKE_SOURCE_DIR}/create-cpackoptions.cmake
)
add_dependencies(main first)
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackOptions.cmake)
include(CPack)
create-cpackoptions.cmake
include(FindSubversion)
Subversion_WC_INFO(${SOURCE_DIR} ${proj_name})
set(revision ${${proj_name}_WC_REVISION})
configure_file(${SOURCE_DIR}/CPackOptions.cmake.in
${BINARY_DIR}/CPackOptions.cmake
#ONLY)
cpackOptions.cmake.in
set(CPACK_PACKAGE_FILE_NAME "#proj_name#-${CPACK_PACKAGE_VERSION}r#revision#-${CPACK_SYSTEM_NAME}")
I have a build/ directory where I'd like CMake to put the *.sln, *.proj, etc. files it generates when I type cmake CMakeLists.txt. How do I do this?
You run cmake in the directory you want to build in with the path from the build directory to the source directory. So say your parent directory is called project and it contains src and build you would:
cd build
cmake ../src
That will put the makefiles and the objects in build while leaving the CMakeLists.txt files in src. The one pitfall is that if there is already a CMakeCache.txt in src then you must delete before running cmake.