This question already has answers here:
Passing an argument to CMAKE via command prompt
(2 answers)
Closed 3 years ago.
Not sure the right way to ask this, but basically, I have a project that I need to build in two slightly different ways. I could have two CMake files and keep them in sync, but I'd prefer to just have one and control it via a command line flag.
Something like cmake --configure . --flag vs cmake --configure ..
And then in the CMakeFile:
ifdef(flag)
line_that_is_different
endif()
to toggle the line on/off.
Obviously this isn't valid CMake, but is there some way to do this in Cmake?
From the command line:
cmake -Dflag=true
cmake -Dflag=On
cmake -Dflag=1
and in your cmake script:
if(flag)
message(STATUS "FLAG IS ON")
endif()
See the cmake manual and cmake if command.
Related
This question already has an answer here:
Hinting Find<name>.cmake Files with a custom directory
(1 answer)
Closed 2 years ago.
I want every CMake project that uses boost (or any other lib) to find it in custom directory, for example /home/someuser/mylibs or C:/mylibs.
To achieve this I may add in CMakeLists.txt following command:
list(APPEND CMAKE_PREFIX_PATH "/home/someuser/mylibs")
This is not very comfortable when I cooperate with different people on different projects. The question is: can I use some environment variable to set it or there's another way to do this?
The usual way is to add -DCMAKE_PREFIX_PATH=/path/to/boost/ when calling CMake to configure your project. But, of course, you can also set an environment variable, e.g. BOOST_DIR and then read it out using CMake:
list(APPEND CMAKE_PREFIX_PATH $ENV{BOOST_DIR})
This question already has an answer here:
CMake - always build specific file
(1 answer)
Closed 2 years ago.
I have a C++ file using __DATE__ to display the build date of my app. But if this file is not modified, it will not be rebuilt and the date will not be updated.
Can CMake always rebuild that specific file?
Apparently it's possible with makefile :
How do you force a makefile to rebuild a target
Edit:
Duplicate of CMake - always build specific file
The solution you trying to apply is a bit against CMake principles since it might lead to the rebuilding of all dependant targets.
However, you can achieve this with an approach like this
add_custom_command(TARGET ${PROJECT_NAME}
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${CMAKE_CURRENT_SOURCE_DIR}/path/file.c)
Update with the 2nd approach:
add_custom_target(file_toucher
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${CMAKE_CURRENT_SOURCE_DIR}/path/file.c)
add_dependencies(${PROJECT_NAME} file_toucher)
This question already has answers here:
cmake: Selecting a generator within CMakeLists.txt
(5 answers)
Closed 3 years ago.
I'm trying to write the CMakeLists.txt for building a custom targets only project.
That is, it's not for the usual C/C++ project; all build recipes are provided using ADD_CUSTOM_COMMAND() and ADD_CUSTOM_TARGET(). The reason why I'm using CMake is to manage dependencies between build target stuffs and utilize the advantages of incremental build.
The problem is, when I execute cmake CMakeLists.txt on Windows cmd.exe, it tries to find Windows SDK or MSBuild.exe -- which are never needed for building targets in the project.
cmd.exe> cmake CMakeLists.txt
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17134.
CMake Error at CMakeLists.txt:6 (PROJECT):
Failed to run MSBuild Command:
MSBuild.exe
to get the value of VCTargetsPath:
Cannot find file
-- Configuring incomplete, errors occurred!
See also "CMakeFiles/CMakeOutput.log"
The header of the CMakeLists.txt is:
cmake_minimum_required ( VERSION 3.0 )
set ( CMAKE_GENERATOR "Unix Makefile" )
set ( CMAKE_VERBOSE_MAKEFILE true )
# Project name
project ( "awesome-project" NONE ) # <language>=NONE for skipping compiler check
...
As I mentioned above, all recipes of the build targets are provided in the CMakeLists.txt; neither Windows SDK nor Visual Studio is required.
I think there is some CMake directives for skipping the invocation of MSBuild, but I could not find it. How can I write the CMakeLists.txt in this case?
As the answer here suggests, setting the CMAKE_GENERATOR variable in the CMake file has no effect when running CMake for the first time. CMake will use the default generator on the first attempt, if no generator is provided via the command line or via environment variable. So try adding the command line option -G to specify the generator like this:
cmake -G "Unix Makefiles" .
Then, on subsequent CMake runs, the generator setting will be cached and you no longer need to provide the -G generator option.
As a side note, you can simply provide the path to your top-level CMakeLists.txt file. So if it's in the current directory, you can just use . for the path.
The documentation is pretty explicit The value of this variable should never be modified by project code. A generator may be selected via the cmake(1) -G option, interactively in cmake-gui(1), or via the CMAKE_GENERATOR environment variable.
You can always make a CMake script that runs CMake with the proper options to create the project.
You may want to keep watch on CMAKE_VERBOSE_MAKEFILE because This variable is a cache entry initialized (to FALSE) by the project() command. I wouldn't be surprised if it doesn't work as shown in your script. Instead You'd probably have to add a -D option on the command line to set it. https://bytefreaks.net/programming-2/make-building-with-cmake-verbose
This question already has answers here:
How to add_custom_target that depends on "make install"
(2 answers)
Closed 6 years ago.
Suppose I use CPack:
include(CPack)
This supposedly adds two extra targets: package and package_source, however if I want to make a post-package target that depends on it like this:
add_custom_target(do_something_to_package ...)
add_dependencies(do_something_to_package package)
I get an error when building, something like this:
make[2]: *** No rule to make target `CMakeFiles/package.dir/all', needed by `CMakeFiles/do_something_to_package.dir/all'. Stop.
Is there a way to make this work?
Ah yes following the How to add_custom_target that depends on "make install" question, this seems to work:
add_custom_target(package_target
COMMAND "${CMAKE_COMMAND}" --build . --target package
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Building package"
DEPENDS stuff_required_for_package
VERBATIM
)
Not exactly elegant, but it could be worse! Also it doesn't seem to play particularly nicely with parallel builds. Not exactly sure why but for release I'd do a non-parallel build just to be safe.
Suppose I have a package called Foo. If I run CMake on a CMakeLists.txt file that contains find_package(Foo), then I can print out the values of variables such as ${Foo_LIBRARIES} and ${Foo_INCLUDES}.
Is there an easy way to display these variables without having to run CMake on a CMakeLists.txt file, and without having to manually inspect the config.cmake file?
You asked: (1) Is there an easy way to display these variables without having to run cmake on a CMakeLists.txt file, and (2) without having to manually inspect the config.cmake file?
I can give you a yes answer to (2) but it does require that you (re)run cmake. But since you can re-run your cmake configure step by simply executing cmake . in the build directory, re-running cmake should not keep you from trying this approach. My answer is given in this SO answer and uses the get_cmake_property command. Here is that code encapsulated into a cmake macro, print_all_variables, so I can use it when debugging my cmake scripts.
macro(print_all_variables)
message(STATUS "print_all_variables------------------------------------------{")
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
message(STATUS "print_all_variables------------------------------------------}")
endmacro()
The macros are invoked with same syntax as cmake functions:
print_all_variables()
To simply print a value, you could do something like this:
message(STATUS "foo include dir: ${foo_INCLUDE}")
where ${foo_INCLUDE} is the value you desire to print.
Note: I'm using cmake > 3.14
Run CMake and have a look at the cache with the ccmake GUI tool. Then you'll get all the variables.
Or run CMake with -LH then you will get all variables printed after configuration.
So I think it is not possible to get the variables without running CMake.
Run cmake in find-package mode. Example to display a package`s include directories:
cmake -DNAME=ZLIB -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=COMPILE --find-package
Example to display the libraries:
cmake -DNAME=ZLIB -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=LINK --find-package
The NAME must be set to the package name. You can obtain your COMPILER_ID on this page. LANGUAGE can be C, CXX or Fortran.
I am always suspicious of variables changing values throughout a script somewhere so I like to see the value of a variable at a particular point in the running script. Combining the ideas from both Phil and Aaron B. this is what I'm using:
function(PRINT_VAR VARNAME)
message(STATUS "${VARNAME}: ${${VARNAME}}")
endfunction()
PRINT_VAR("CMAKE_CXX_COMPILER")
Then I can just litter PRINT_VAR statements around like I'm debugging code back in 1980
These variables are generally hardcoded into FindFoo.cmake so that it is not possible to extract them without running the function first. Note that sometimes the value of Foo_LIBRARIES depends on the system configuration, which is unknown until find_package(Foo) is run.