CMAKE_SYSTEM_NAME blank? - cmake

I am trying to compile for Linux (with Generator Eclipse CDT4 - Ninja) but when I am checking for ${CMAKE_SYSTEM_NAME} in CMakeLists.txt, all I get is blank.
In which scenarios is using this variable valid?
Using cmake 3.02 from Debian Testing.

You need to place CMAKE_SYSTEM_NAME after project command:
message("CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
project(Foo)
message("CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
Result:
CMAKE_SYSTEM_NAME:
-- The C compiler identification is GNU 4.9.1
...
-- Detecting CXX compiler ABI info - done
CMAKE_SYSTEM_NAME: Linux

I have the same issue, and work it out.
All i want to do is cross compile on Linux server with aarch64-himix100-linux, and compile with the default toolchain on Darwin system.
I use CMAKE_HOST_SYSTEM_NAME instead of CMAKE_SYSTEM_NAME.
The value of CMAKE_HOST_SYSTEM_NAME is equal to the output of uname -s.
For example,
cmake_minimum_required(VERSION 3.8)
if (NOT ${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/Toolchain-aarch64-himix100-linux.cmake")
endif ()
project(phoenix)

Related

cmake cannot find an existing directory on mingw64 (msys2)

I am trying to compile a project under MSYS2 and CLANG64 environment.
I have previously compiled dependencies in /usr/local.
$ ls /usr/local/include
boost compat-5.3.c cryptopp lauxlib.h libmongoc-1.0 lua.hpp luajit.h mongocxx yaml-cpp
bsoncxx compat-5.3.h gtest libbson-1.0 lua.h luaconf.h lualib.h tsl
$ ls /usr/local/lib
cmake libboost_filesystem-mt-s-x64.a libbson-static-1.0.a libmongoc-1.0.dll.a
libboost_atomic-mt-s-x64.a libboost_program_options-mt-s-x64.a libbsoncxx-static.a libmongoc-static-1.0.a
libboost_atomic-mt-x64.a libboost_regex-mt-s-x64.a libcryptopp.a libmongocxx-static.a
libboost_chrono-mt-s-x64.a libboost_system-mt-s-x64.a libgtest.a libyaml-cpp.a
libboost_container-mt-s-x64.a libboost_thread-mt-s-x64.a libgtest_main.a pkgconfig
libboost_context-mt-s-x64.a libbson-1.0.dll.a liblua-compat.a
But when I create the project, I explicitly set the location of binaries with interface libraries as I don't want to rely on the find mechanism that has hurt me badly in the past - linking to unintended, old system libraries.
project(test)
cmake_minimum_required( VERSION 3.0 )
add_library( cryptopp STATIC IMPORTED GLOBAL )
set_target_properties( cryptopp PROPERTIES
IMPORTED_LOCATION "/usr/local/lib/libcryptopp.a"
INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include"
INTERFACE_COMPILE_DEFINITIONS "HAVE_CRYPTOPP"
)
add_executable( test test.cpp )
target_link_libraries( test cryptopp )
This works perfect under all Linux distros - Redhat, Ubuntu, etc but fails in MSYS2.
However when I run cmake, I get an error stating that /usr/local/include does not exist.
$ cmake ..
-- Building for: Ninja
-- The C compiler identification is Clang 14.0.4
-- The CXX compiler identification is Clang 14.0.4
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: G:/msys64/clang64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: G:/msys64/clang64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
CMake Error in CMakeLists.txt:
Imported target "cryptopp" includes non-existent path
"/usr/local/include"
in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
* The path was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and references files it does not
provide.
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
I just cannot figure out why this is happening. Any clues?
Maybe it's a Windows path issue. Try replacing /usr/local with the output of cygpath -m /usr/local.

cmake move build files in a subdirectory after configuring and building [duplicate]

I'm using cmake to compile a C++ project, and I want cmake to generate all the output files(metafiles like Makefile used to create binaries) in the build folder. I've checked all the answers in How do I make cmake output into a 'bin' dir?, none of them worked for me(suprisingly!). Files are generated in the root folder instead of in the build folder, what's wrong here? I guess I must have missed something.
Code Structure
➜ cmake-test tree .
.
├── CMakeLists.txt
└── hello.cpp
0 directories, 2 files
CMakeLists.txt
# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.11)
# Project's name
project(hello)
# Set the output folder where your program will be created
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# The following folder will be included
include_directories("${PROJECT_SOURCE_DIR}")
add_executable(hello ${PROJECT_SOURCE_DIR}/hello.cpp)
Build Commands and Outputs
➜ cmake-test cmake .
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/searene/CLionProjects/cmake-test
➜ cmake-test ls
bin CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt hello.cpp Makefile
cmake version
➜ cmake-test cmake --version
cmake version 3.11.4
CMake suite maintained and supported by Kitware (kitware.com/cmake).
OS
Linux
The usual way to do this, rather than changing variables to set the path, is simply to create the output directory, change to it, and run cmake from there. So instead of cmake . you usually have cmake .. or similar.
I understand the initial impulse to say "But I expect my build system to write output somewhere else." But CMake is not usually used in the way you were initially expecting, and other people who run your CMake build won't expect what you were expecting, so it's probably best to just use the built-in, default behavior, which is to put the output wherever cmake was run.
Put another way: You are fighting against the tool. Don't do that.
Disclaimer: I recommend going with #john-zwinck's answer.
By default, cmake uses the current working directory as build directory and whatever path you provide as source directory. So the normal way of achieving your goal is
create the build directory (mkdir build)
go there (cd build)
call cmake with the source dir as argument (cmake path/to/source)
BUT there is another way, as far as I know not documented in the cmake docs and only kept for compatibility reasons or internal usage, that some people are using. The -B and -H flags
cmake -Hpath/to/source -Bpath/to/build
or even from the source dir
cmake . -Bbuild
Important: no space after -B.
CMake 3.19.1 (not sure how about older ones) has following option (from docs):
cmake [<options>] -S <path-to-source> -B <path-to-build>
Uses as the build tree and as the
source tree. The specified paths may be absolute or relative to the
current working directory. The source tree must contain a
CMakeLists.txt file. The build tree will be created automatically if
it does not already exist. For example:
cmake -S src -B build

How to check the NVCC version with CMake 3.15?

How does one check the version of NVCC, with CMake 3.15 (not 3.17 or later)?
I suppose I could write my own module to run it with --version, but is there an easier way to do it?
In CMake 3.15 with CUDA language support enabled, the CMAKE_CUDA_COMPILER_VERSION variable is defined and contains the correct version. MRE:
cmake_minimum_required(VERSION 3.15)
project(test LANGUAGES CUDA)
message(STATUS "CMAKE_CUDA_COMPILER = ${CMAKE_CUDA_COMPILER}")
message(STATUS "CMAKE_CUDA_COMPILER_ID = ${CMAKE_CUDA_COMPILER_ID}")
message(STATUS "CMAKE_CUDA_COMPILER_VERSION = ${CMAKE_CUDA_COMPILER_VERSION}")
Output:
$ cmake-3.15 -S . -B build
-- The CUDA compiler identification is NVIDIA 10.1.243
-- Check for working CUDA compiler: /usr/bin/nvcc
-- Check for working CUDA compiler: /usr/bin/nvcc -- works
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- CMAKE_CUDA_COMPILER = /usr/bin/nvcc
-- CMAKE_CUDA_COMPILER_ID = NVIDIA
-- CMAKE_CUDA_COMPILER_VERSION = 10.1.243
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
I have various versions of CMake installed as cmake-3.XX, I assume you would simply run cmake.

why can't wsl be called from cmake scripts?

I have bash scripts that generate c++ files and I would like to call them from an add_custom_command() in cmake. On windows, I'd like to call the bash script through wsl (windows subsytem for linux). cmake configures fine (finding wsl.exe), but on build it complains that:
'C:\Windows\System32\wsl.exe' is not recognized as an internal or external command,
Here is a simple cmake script to recreate. It succeeds in a linux environment (including wsl), but fails in the native windows environment.
cmake_minimum_required(VERSION 3.7)
project(WhyNotWSL)
set(source ${CMAKE_SOURCE_DIR}/Input/main.cpp)
set(target generated.cpp )
if (WIN32)
find_program(WSL wsl)
message("WSL is ${WSL}")
set (command ${WSL} cp ${source} ${target})
else()
set (command cp ${source} ${target})
endif()
message("command is ${command}")
add_custom_target( ${target} )
add_custom_command(
OUTPUT ${target}
COMMAND ${command}
DEPENDS ${source}
COMMENT "Generated ${target}"
)
add_custom_target(p ALL
DEPENDS ${target}
)
add_executable(hello ${target})
The following output is from cmake configure:
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.18363.
-- The C compiler identification is MSVC 19.27.29110.0
-- The CXX compiler identification is MSVC 19.27.29110.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.29110/
bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.2911
0/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
**WSL is C:/Windows/System32/wsl.exe**
**command is C:/Windows/System32/wsl.exe;cp;D:/Development/CMakeWSLTest/Input/main.cpp;generated.cpp**
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Development/CMakeWSLTest/BUILD
And the following is the output from cmake build
Microsoft (R) Build Engine version 16.7.0+b89cb5fde for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule D:/Development/CMakeWSLTest/CMakeLists.txt
Building Custom Rule D:/Development/CMakeWSLTest/CMakeLists.txt
Generated generated.cpp
'C:\Windows\System32\wsl.exe' is not recognized as an internal or external command,
operable program or batch file.
For the record, the following works from a DOS shell:
>C:\Windows\System32\wsl.exe cp ../Input/main.cpp generated.cpp
Try giving HINTS to find_program() and point to C:\Windows\Sysnative
Something like this:
if (WIN32)
find_program(WSL wsl HINTS C:/Windows/Sysnative)
message("WSL is ${WSL}")
set (command ${WSL} cp ${source} ${target})
else()
set (command cp ${source} ${target})
endif()
Rationale here: https://superuser.com/a/1528297/2201 but basicly, this could be caused by your cmake buil. find_program() finds executable with absolute path that then should be different when it actually gets called during the build, it should actually point the binary from another location due to inherited build type of parent process of your build.
Maybe..

Specify CMake generator unless explicitly passed as command argument by user

In all of the following, I'm using Windows, so WIN32 is always defined in CMake.
I have a CMakeLists.txt file which does its job fine, and I'm using a Preload.CMake file to specify a bunch of stuff, including a certain generator depending on circumstances:
if( WIN32 )
message( "Current generator: ${CMAKE_GENERATOR}" ) # For debugging purposes
if( NOT COMMAND cl OR NOT COMMAND nmake )
set( CMAKE_CXX_COMPILER "g++" )
set( CMAKE_GENERATOR "MinGW Makefiles" CACHE STRING "" FORCE )
set( CMAKE_MAKE_PROGRAM "make" )
message( "MSVC compiler could not be found, attempting with g++ and MinGW makefiles." )
endif( )
endif( )
This allows a Windows user with no Visual Studio to run cmake .. instead of a whole cmake .. -G "MinGW Makefiles".
It works pretty well, here is the output when cmake .. is run from an empty directory (no cache, no nothing):
Current generator:
MSVC compiler could not be found, attempting with g++ and MinGW makefiles.
Windows detected, forcing static libs.
-- The CXX compiler identification is GNU 8.2.0
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/SAYENS/Desktop/picross/build
The problem with this is when I want to specify a generator through the command line. Here is what happens when I run cmake .. -G "MSYS Makefiles" from a MSYS terminal (empty directory, no cache):
Current generator:
MSVC compiler could not be found, attempting with g++ and MinGW makefiles.
CMake Error: Error: generator : MSYS Makefiles
Does not match the generator used previously: MinGW Makefiles
Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.
(There is no such file as CMakeCache.txt or a CMakeFiles directory, but explicitly specifying a generator in the command line, that is different from the one specified in Preload.CMake, seems to be enough of a source of confusion to print out this message.)
I thought I'd be able to work around the issue by "catching" the value of the -G argument with CMAKE_GENERATOR, but it turns out I can't, as per the first output line Current generator:.
How can I work this out? I tried looking for a way to parse command line arguments, but found none that doesn't involve using a wrapper script, which I'd like to avoid resorting to.
Set the generator name in the environment variable CMAKE_GENERATOR. The documentation says:
Specifies the CMake default generator to use when no generator is
supplied with -G. If the provided value doesn’t name a generator known
by CMake, the internal default is used. Either way the resulting
generator selection is stored in the CMAKE_GENERATOR variable.
Some generators may be additionally configured using the environment
variables:
CMAKE_GENERATOR_PLATFORM
CMAKE_GENERATOR_TOOLSET
CMAKE_GENERATOR_INSTANCE