Graceful fail with cmake [duplicate] - cmake

find_package(GTK)
How can I make it output something so that I can know whether it finds something or not?
Platform: windows XP

You can use the message command as in:
FIND_PACKAGE(GTK)
IF (${GTK_FOUND})
MESSAGE(STATUS "Found GTK.")
ELSE (${GTK_FOUND})
MESSAGE(STATUS "Could not locate GTK.")
ENDIF (${GTK_FOUND})
Or, if you want it to abort if GTK isn't found:
FIND_PACKAGE(GTK)
IF (${GTK_FOUND})
MESSAGE(STATUS "Found GTK.")
ELSE (${GTK_FOUND})
MESSAGE(FATAL_ERROR "Could not locate GTK.")
ENDIF (${GTK_FOUND})
Note that if you do the latter, then you can simply use the "REQUIRED" flag with FIND_PACKAGE, as specifying the "REQUIRED" flag ensures that it will fail with an error if it isn't found:
FIND_PACKAGE(GTK REQUIRED)
The command above will cause CMake to abort and print an error message if GTK is not found. You may also be interested in the documentation for FIND_PACKAGE from the CMake Manual. Also, one should note that FIND_PACKAGE(XYZ) actually invokes the CMake module FindXYZ, and so each package with a corresponding FIND_PACKAGE has its own CMake module implementing the find operation... since CMake is stilll somewhat new, some of those find modules are not correctly implemented... based on your comments below, it would seem that FindGTK has not been implemented correctly (since if it isn't present, the use of the REQUIRED flag should cause it to abort with a fatal error, but does not seem to do so in your case).

Related

How to provide a customized error message if Cmake find_package cannot find a package?

suppose a CMakeList.txt has the line find_package(Qt6 COMPONENTS Core)
however, the user doesn't configure the environment with QT correctly, so Cmake will just show that it cannot find Qt6.
I would like to provide a customized message like "Cannot find Qt6, maybe try cmake -DCMAKE_PREFIX_PATH=/path/to/qt/6.2.3/macos"
is it possible to achieve the goal?
By passing QUIET to find_package call you could disable standard message. After the call you could check value of *_FOUND variable for determine, whether find_package has been succeeded or not, and print corresponding message. Something like that:
find_package(Qt6 QUIET COMPONENTS Core)
if (Qt6_FOUND)
# Success
message(STATUS "Found Qt6")
else()
# Fail
message(FATAL_ERROR "Cannot find Qt6, maybe try 'cmake -DCMAKE_PREFIX_PATH=/path/to/qt/6.2.3/macos'")
endif()
In the else branch the keyword FATAL_ERROR ensures that CMake will stop executing after printing the message. This is a standard workflow for projects when required dependencies are not found. However, if your project is developed to work without Qt6 too, you could omit FATAL_ERROR and use any other keyword for message call.

CMake Deprecation Warning :" message(DEPRECATION “The CMAKE_FORCE_C_COMPILER macro is deprecated

We are using CMake 3.12.0. I am using the below CMake script for compilation. While I am compiling the code I got a warning like
message(DEPRECATION “The CMAKE_FORCE_C_COMPILER macro is deprecated. "
“Instead, just set CMAKE_C_COMPILER and allow CMAKE to identify the compiler.”)” .
May I know how to fix this issue?
We are using Rh850 based compiler and windows10 machine. Let me know if any other information is required from my side.
CMake Script:
# Change Compiler to RH850
set(CMAKE_C_COMPILER “${COMPILER_PATH}/ccv850.exe”)
set(CMAKE_CXX_COMPILER “${COMPILER_PATH}/cxv850.exe”)
#TODO set dependency files (.d) to the correct location for compiler id check and remove FORCE’s
CMAKE_FORCE_C_COMPILER("${COMPILER_PATH}/ccv850.exe" “ARM”)
CMAKE_FORCE_CXX_COMPILER("${COMPILER_PATH}/cxv850.exe" “ARM”)
May I know how to fix this warning instead of suppress it.

Why does CMake ignore exported CXX and CC environment variables?

I am running a CMake (3.4.3) like this as explained in the CMake FAQ's:
export CC="cc_args.py $PWD/../bin/gcc"
export CXX="cc_args.py $PWD/../bin/g++"
cmake -DCMAKE_BUILD_TYPE=Debug ..
However when I print CMAKE_CXX_COMPILER and CMAKE_C_COMPILER it still points to the system's default compilers in /usr/bin. It only works when I explicitly read-in the environment variables like this:
IF (NOT $ENV{CC} STREQUAL "")
SET(CMAKE_C_COMPILER $ENV{CC})
ENDIF ()
IF (NOT $ENV{CXX} STREQUAL "")
SET(CMAKE_CXX_COMPILER $ENV{CXX})
ENDIF ()
But even then the building fails with this message:
/bin/sh: 1: /home/peterg/bin/cc_args.py /home/peterg/Code/build/../bin/g++: not found
However I am certain that all paths are correct since executing just the path between the two colons outputs this as expected:
g++: fatal error: no input files
compilation terminated.
Update:
It seems the compiling process does not like spaces in the compiler paths. I've now created two scripts (one for GCC and one for CC) which wrap the commands and propagate the arguments and that seems to work. But it still seems I am doing something fundamentally wrong because CMake would also not accept the exported CC=proxy_script_cc.sh and GCC=proxy_script_gcc.sh variables without spaces by itself.
Turning my comment into an answer
Problem
I've given you code a try and could reproduce your problem
CMake Error at [...]/cmake-3.5/Modules/CMakeDetermineCXXCompiler.cmake:56 (message):
Could not find compiler set in environment variable CXX:
cc_args.py [... PWD ...]/../bin/g++.
If I look at CMakeDetermineCXXCompiler.cmake code and at get_filename_component() documentation, it just means that it didn't find cc_args.py in "the system search path" or relative to your binary output directory.
Solution
So it does work when you give a full path or a relative path to your binary output dir with something like
export CC="../cc_args.py ../bin/gcc"
export CXX="../cc_args.py ../bin/g++"
Alternative
CMake does allow to define "launcher scripts" e.g. with CMAKE_<LANG>_COMPILER_LAUNCHER
$ cmake -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_COMPILER_LAUNCHER=../cc_args.py
-DCMAKE_CXX_COMPILER_LAUNCHER=../cc_args.py
..
References
How to Use CCache with CMake?
Save and reprint warnings for successfully-compiled files on subsequent builds?
Pass -DCMAKE_CXX_COMPILER=<path/to/compiler> to your CMake call. That's less error prone compared to fiddling with shell variables.

CMake not throwing error when expected

My FindEigen.cmake is as follows:
find_path(EIGEN_INCLUDE_DIR NAMES Eigen/Core
PATHS
PATH_SUFFIXES eigen3
${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty
/usr/local/include
/usr/local/homebrew/include # Mac OS X
/opt/local/var/macports/software # Mac OS X
/opt/local/include
/usr/include)
# handle the QUIETLY and REQUIRED arguments and set EIGEN_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EIGEN DEFAULT_MSG EIGEN_INCLUDE_DIR)
This is called from my CMakeLists.txt file as follows:
find_package(Eigen REQUIRED)
The message I get back from the cmake gui is:
Could NOT find EIGEN (missing: EIGEN_INCLUDE_DIR)
but this is not an error and the configuration completes successfully. My understanding is that the REQUIRED option means that cmake should throw an error and halt if the package isn't found, and that the FIND_PACKAGE_HANDLE_STANDARD_ARGS method should enforce that. But this isn't happening for me. Any ideas why not?
I just had a similar problem which was caused by the different naming used for the Eigen library in find_package(Eigen REQUIRED) and find_package_handle_standard_args(EIGEN). E.g. you need to change EIGEN to Eigen.
Using the same naming in both places should fix this, along with the REQUIRED_VARS as suggested by #debris.
try using required_vars
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EIGEN REQUIRED_VARS EIGEN_INCLUDE_DIR)

How do I view the CMake command line statement that Qt Creator executes?

I'm attempting to debug a command line CMake failure. The same CMake file works in Qt Creator, with the arguments in the Qt Creator window matching what I have entered on the command line.
This makes me think Qt Creator is adding some extra arguments, which makes sense since the generator drop down has several options that specify architecture and CMake version.
Is there a way to get the CMake command that Qt Creator executed to produce the desired result, specifically the arguments passed to the CMake executable?
I found one post that talks about viewing the CMakeCache files to do some forensics, but this only proves there are differences, it doesn't quickly show me what arguments to change.
Try adding the following block to the end of your CMakeLists.txt and running CMake from Qt Creator again. The CMake output should list all variables that have been passed via the -D command line argument.
get_cmake_property(CacheVars CACHE_VARIABLES)
foreach(CacheVar ${CacheVars})
get_property(CacheVarHelpString CACHE ${CacheVar} PROPERTY HELPSTRING)
if(CacheVarHelpString STREQUAL "No help, variable specified on the command line.")
get_property(CacheVarType CACHE ${CacheVar} PROPERTY TYPE)
if(CacheVarType STREQUAL "UNINITIALIZED")
set(CacheVarType)
else()
set(CacheVarType :${CacheVarType})
endif()
set(CMakeArgs "${CMakeArgs} -D${CacheVar}${CacheVarType}=\"${${CacheVar}}\"")
endif()
endforeach()
message("CMakeArgs: ${CMakeArgs}")
For more info, see this answer.
This won't show what generator was selected (if any) via the -G arg. To find that, you need to look for CMAKE_GENERATOR:INTERNAL=... in your CMakeCache.txt
If this doesn't help you identify the overall problem, you should probably heed #arrowdodger's advice and post more details about the errors you're getting and your two build environments. For example, an error could be caused simply by running CMake from a subdirectory of the source tree.