How to print variables in CMake? - c++

I want to use cmake to build my project, my CMakeLists.txt is very simple:
cmake_minimum_required(VERSION 3.20)
project(YuvParallelProcess)
message("$(PROJECT_SOURCE_DIR)")
include_directories($(PROJECT_SOURCE_DIR)/inc)
link_directories($(PROJECT_SOURCE_DIR)/lib/libyuv)
add_executable(YuvParallelProcess $(PROJECT_SOURCE_DIR)/src/main.cpp)
target_link_libraries(YuvParallelProcess libyuv.a)
my project files are organized as follows:
YuvParallelProcess
build
data
inc
lib
src
CMakeLists.txt
when I run cmake .. in build directory, the shell prints:
$(PROJECT_SOURCE_DIR)
-- Configuring done
CMake Error at CMakeLists.txt:10 (add_executable):
Cannot find source file:
$(PROJECT_SOURCE_DIR)/src/main.cpp
CMake Error at CMakeLists.txt:10 (add_executable):
No SOURCES given to target: YuvParallelProcess
I don't know why the shell just prints $(PROJECT_SOURCE_DIR) other than the value of PROJECT_SOURCE_DIR
How can I print the value of PROJECT_SOURCE_DIR
By the way, I can't figure out why cmake failed to compile my project

Cmake uses curly braces for getting values of variables:
${PROJECT_SOURCE_DIR}
I suggest to dump messages like below to not skip empty messages.
message(PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}")
Cmake failed to configure your project because it did not recognise variables in parentheses and considered $(PROJECT_SOURCE_DIR) to be a string literal as is.
There is CMakePrintHelpers Cmake module for dumping variables exactly like above.
include(CMakePrintHelpers)
cmake_print_variables(PROJECT_SOURCE_DIR)

Instead of using message, you can also use cmake_print_variables to display variables.
in this case, you must include CMakePrintHelpers
include(CMakePrintHelpers)
cmake_print_variables(PROJECT_SOURCE_DIR)
The ouput will be :
-- PROJECT_SOURCE_DIR="path/to/your/project"
With cmake_print_variables you can also display several variables, like this:
cmake_print_variables(PROJECT_SOURCE_DIR ANOTHER_VARIABLE)
The ouput will be :
-- PROJECT_SOURCE_DIR="path/to/your/project" ; ANOTHER_VARIABLE="other variable"

Related

CMake command line define macro without value

I have the following line in my CMakeLists.txt
add_compile_definitions(DEBUG=$(DEBUG))
so when I compile my code with Makefile, I can do this
make DEBUG=1
But what I really want is to just define the DEBUG macro without setting any value to it.
Is there a way I can do this on a command line with cmake?
With CMake you can, at configuration time, add some CMake variables. For example you can do this cmake -S <src_folder> -B <build_folder> -DDEBUG=ON. This way you will have access to the variable DEBUG in your CMake.
In your CMake you will have this code
if(DEBUG)
add_compile_definition(DEBUG)
endif()
(Note that instead of add_compile_definitions, it is recommended to use target_compile_definitions which will set your DEBUG macro only for one target and not globally to your project.
Example:
add_executable(my_target main.cpp)
target_compile_definition(my_target PRIVATE DEBUG)
PRIVATE means that this compile_definition will only be used by the target my_target and will not be propagated to others.)
But if you're only concern of the building type, I suggest that you use CMake variables that are already present within CMake. You can use CMAKE_BUILD_TYPE which will contains Debug, Release or whatever depending on what type of build you want. Your code will now be this
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_compile_definition(DEBUG)
endif()
And you can use this command line cmake -S <src_folder> -B <build_folder> -DCMAKE_BUILD_TYPE=Debug
And here the documentation https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
Note that this solution will only works for Mono-config generators like Makefile or Ninja and will not works with Visual Studio or Xcode

why can CMake Build files not be generated correctly

I am trying a simple test to see if CMake is working on my windows system correctly.
I keep getting a error.
Here is the command with the error.
cmake .
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- Configuring done
CMake Error at CMakeLists.txt:5 (add_executable):
No SOURCES given to target: main.cpp
CMake Generate step failed. Build files cannot be regenerated correctly.
code for file named main.cpp
#include <iostream>
int main()
{
std::cout << "hello world\n" << "this is a test" <<std::endl;
}
and my CMake file
cmake_minimum_required(VERSION 3.10)
project(test)
add_executable(main.cpp)
I have used CMake in Linux before so not sure why this is failed.
I used Microsoft package manager to install it.
I am using the command line for this, i tried the GUI it also failed.
I have also deleted the CMake files and cache multiple times.
I have not been able to find anything online.
Can't add a comment since my reputation is too low, so I will write an answer instead. In the last line of your CMakeLists.txt file
add_executable(main.cpp)
you are missing the name of the executable
add_executable(name_exe main.cpp)
CMake is telling you that in the error message. CMake tries to create a target main.cpp without source files, since CMake suggests the name of the executable at the first place in the command add_executable().

why i have some missing files when cmake generate build folder ? (Maya 2020 - CMake 3.16.4 - VS 2017)

I exactly followed the instruction in API help to create visual studio project:
The CMakeLists.txt File guide
but I got this error:
CMake Warning (dev) in CMakeLists.txt:
No project() command is present. The top-level CMakeLists.txt file must
contain a literal, direct call to the project() command. Add a line of
code such as
project(ProjectName)
near the top of the file, but after cmake_minimum_required().
CMake is pretending there is a "project(Project)" command on the first
line.
This warning is for project developers. Use -Wno-dev to suppress it.
by the way , this error didn't stop the process and CMake generate the build folder for me
but as you can see it didn't create some files i think , there are no helloworld.vcxproj & helloworld.vcxproj.filters
FYI : i use Cmake 3.16.4 and visual studio 2017
The tutorial is incomplete, as it is missing the project() command. Your CMake project should always have at least one project() command, as it is used to initialize some pretty essential variables, and the language used in the CMake file, among other things. From the CMake documentation:
The top-level CMakeLists.txt file for a project must contain a literal, direct call to the project() command; loading one through the include() command is not sufficient. If no such call exists, CMake will issue a warning and pretend there is a project(Project) at the top to enable the default languages (C and CXX).
Using the set() command to initialize PROJECT_NAME is bad practice, as the project() call also does this for you. I would suggest modifying the CMake file to include the project() command instead:
cmake_minimum_required(VERSION 2.8)
include($ENV{DEVKIT_LOCATION}/cmake/pluginEntry.cmake)
# Set the project here.
project(exampleNode)
set(RESOURCES_FILES myResource.xpm)
set(MEL_FILES
exampleNode.mel)
set(SOURCE_FILES
exampleNode.cpp
${MEL_FILES}
)
set(LIBRARIES
OpenMaya Foundation
)
find_package(MtoA)
find_alembic()
build_plugin()
this is the correct CMakeLists.txt :
cmake_minimum_required(VERSION 2.8)
project(test)
set(PROJECT_NAME test)
include($ENV{DEVKIT_LOCATION}/cmake/pluginEntry.cmake)
set(RESOURCES_FILES myResource.xpm)
set(MEL_FILES
test.mel)
set(SOURCE_FILES
test.cpp
${MEL_FILES}
)
set(LIBRARIES
OpenMaya Foundation
)
build_plugin()

Add a subproject by CMake

Apache Arrow submodule is stored at thirdparty/apache_arrow/cpp, so my main CMakeLists.txt looks like
cmake_minimum_required(VERSION 3.0.0)
project(arrow_parcer VERSION 0.1.0)
add_subdirectory(src)
add_subdirectory(thirdparty/apache_arrow/cpp)
At the thirdparty/apache_arrow stored whole Apache Arrow project.
When I'm trying to build project, last output lines is follow:
[cmake] CMake Error: INSTALL(EXPORT) given unknown export "arrow_targets"
[cmake] Generating done
[cms-driver] Error during CMake configure: [cmake-server] Failed to compute build system.
Apache Arrow can be easily builded by CMakeLists.txt at /cpp folder, but why there is an error if I trying to include it by add_subdirectory?
Apache Arrow C++ is not meant to be built using add_subdirectory, instead you should use CMake's ExternalProject_Add facility to build it:
ExternalProject_Add(arrow_ep
URL "https://www.apache.org/dist/arrow/arrow-0.15.1/apache-arrow-0.15.1.tar.gz"
SOURCE_SUBDIR cpp)
Instead of using URL you can also use different providers like GIT_REPOSITORY, too.
If you don't really need to setup the installation, here is a hack-y way to do this. In the CMakeLists.txt adding arrow's source dir, you define your own install.
function(install)
endfunction()
add_subdirectory(${arrow_SOURCE_DIR}/cpp ${arrow_BINARY_DIR})

CMake won't build without set_source_files_properties with LANGUAGE CXX

I have a small library that I have made (mostly wrappers for a more obtuse library underneath) which I have been compiling and using no problem in a contained project. I am now using this library in another project and have attempted to change the CMakeLists.txt appropriately (see below).
cmake_minimum_required (VERSION 3.5)
set(project "foobar")
project(${project} LANGUAGES CXX)
set(${project}_VERSION_MAJOR 0)
set(${project}_VERSION_MINOR 1)
add_library(${project} SHARED
./driver/foo.h
./driver/foo.c
./bar.cpp
./bar.hpp)
set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX)
target_compile_features(${project}
PUBLIC
cxx_std_11)
target_include_directories(${project} PUBLIC ./driver/ .)
set_target_properties(${project} PROPERTIES LINKER_LANGUAGE CXX)
add_executable(bno055-test
./testingProject.cpp
)
target_link_libraries(test ${project})
install(
TARGETS ${project}
RUNTIME DESTINATION bin)
The error I have encountered is with the line set_source_files_properties(./driver/foo.c PROPERTIES LANGUAGE CXX). When it comes to compiling this C file with the C++ flag above I get many warnings of the type clang-8: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]. This is expected, as I am using deprecated methods and should not be compiling this file using the C++ flag. However, whenever I remove this line, or alter it to specify C instead of C++, my entire project no longer builds and fails with error:
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_C_COMPILE_OBJECT
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
Makefile:283: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1
"/usr/bin/make -j4 all" terminated with exit code 2. Build might be incomplete.
I'm not familiar enough with CMake to see why this line of code and error are related like this. Is there some alternative piece of code I should include to create the missing variable CMAKE_C_COMPILE_OBJECT?
I assume that when I initially created this project using Eclipse this line was automatically generated and I am unclear as to why it now creates a problem when I had been compiling these files with the same CMakeLists.txt before (without library linking).
This is with clang#8.0.0 on Ubuntu 16.04.
Any help would be much appreciated! Apologies if I have missed something simple!
Is there some alternative piece of code I should include to create the missing variable CMAKE_C_COMPILE_OBJECT?
No, as the CMake error states, this is an "internal CMake variable" which should be initialized by CMake. It is not something you should have to set yourself. It should be set indirectly when you call project(). However, you only tell CMake you are using C++ (with CXX option) in the project() command. If you want CMake to make use of C and C++, you need to add both:
project(${project} LANGUAGES C CXX)
Even better, CMake enables C and C++ by default, so you can simply do:
project(${project})