cmake cross-compilation toolchain confusion - cmake

TL;DR: Why moving stuff around from the CMakeLists.txt to a dedicated toolchain file plays a role for find_package?
Trying to cross-compile with cmake and compile/link against pthread, I have the following dummy source file and CMakeLists.txt which work as expected together:
main.cc
#include <iostream>
#include <bits/c++config.h> // needed in the real world
int main()
{
std::cout << "Hello World !\n";
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(test VERSION 0.0.1)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf)
add_compile_options(-mtune=cortex-a9)
add_compile_definitions(_ARM_GCC_)
# Looking for cross compiler includes; maybe looking for rootfs-like stuff would be better
file(GLOB cross_includes LIST_DIRECTORIES true "/usr/arm-linux-gnueabihf/include/c++/*/arm-linux-gnueabihf/")
include_directories(SYSTEM ${cross_includes})
include_directories(SYSTEM /usr/arm-linux-gnueabihf/include)
find_package(Threads REQUIRED) # Not strictly necessary in this example but needed in the real world
add_executable(test main.cc)
Test:
$> rm -rf build/ && cmake -B build/ && make VERBOSE=1 -C build/
-- The C compiler identification is Clang 11.0.1
-- The CXX compiler identification is Clang 11.0.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/clang - 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: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jp/sandbox/so/cmake/build
make: Entering directory '/home/jp/sandbox/so/cmake/build'
/usr/bin/cmake -S/home/jp/sandbox/so/cmake -B/home/jp/sandbox/so/cmake/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/jp/sandbox/so/cmake/build/CMakeFiles /home/jp/sandbox/so/cmake/build//CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/jp/sandbox/so/cmake/build'
make -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/depend
make[2]: Entering directory '/home/jp/sandbox/so/cmake/build'
cd /home/jp/sandbox/so/cmake/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/jp/sandbox/so/cmake /home/jp/sandbox/so/cmake /home/jp/sandbox/so/cmake/build /home/jp/sandbox/so/cmake/build /home/jp/sandbox/so/cmake/build/CMakeFiles/test.dir/DependInfo.cmake --color=
Dependee "/home/jp/sandbox/so/cmake/build/CMakeFiles/test.dir/DependInfo.cmake" is newer than depender "/home/jp/sandbox/so/cmake/build/CMakeFiles/test.dir/depend.internal".
Dependee "/home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/jp/sandbox/so/cmake/build/CMakeFiles/test.dir/depend.internal".
Scanning dependencies of target test
make[2]: Leaving directory '/home/jp/sandbox/so/cmake/build'
make -f CMakeFiles/test.dir/build.make CMakeFiles/test.dir/build
make[2]: Entering directory '/home/jp/sandbox/so/cmake/build'
[ 50%] Building CXX object CMakeFiles/test.dir/main.cc.o
/usr/bin/clang++ --target=arm-linux-gnueabihf -D_ARM_GCC_ -isystem /usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf -isystem /usr/arm-linux-gnueabihf/include -g -mtune=cortex-a9 -std=c++17 -o CMakeFiles/test.dir/main.cc.o -c /home/jp/sandbox/so/cmake/main.cc
[100%] Linking CXX executable test
/usr/bin/cmake -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
/usr/bin/clang++ --target=arm-linux-gnueabihf -g -rdynamic CMakeFiles/test.dir/main.cc.o -o test
make[2]: Leaving directory '/home/jp/sandbox/so/cmake/build'
[100%] Built target test
make[1]: Leaving directory '/home/jp/sandbox/so/cmake/build'
/usr/bin/cmake -E cmake_progress_start /home/jp/sandbox/so/cmake/build/CMakeFiles 0
make: Leaving directory '/home/jp/sandbox/so/cmake/build'
So far, everything works fine.
Now, the tricky part: I'd like to put the cross-compilation specific stuff in a toolchain.cmake file
toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf)
add_compile_options(-mtune=cortex-a9)
add_compile_definitions(_ARM_GCC_)
# Looking for cross compiler includes; maybe looking for rootfs-like stuff would be better
file(GLOB cross_includes LIST_DIRECTORIES true "/usr/arm-linux-gnueabihf/include/c++/*/arm-linux-gnueabihf/")
include_directories(SYSTEM ${cross_includes})
include_directories(SYSTEM /usr/arm-linux-gnueabihf/include)
new CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(test VERSION 0.0.1)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Threads REQUIRED) # Not strictly necessary in this example but needed in the real world
add_executable(test main.cc)
Test:
$> rm -rf build/ && cmake -B build/ -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake && make VERBOSE=1 -C build/
-- The C compiler identification is Clang 11.0.1
-- The CXX compiler identification is Clang 11.0.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/clang - 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: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - not found
CMake Error at /usr/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:165 (message):
Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
/usr/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:458 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.18/Modules/FindThreads.cmake:234 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:11 (find_package)
-- Configuring incomplete, errors occurred!
See also "/home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeOutput.log".
See also "/home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeError.log".
Actually, cmake finds pthread.h but clang cannot compile it (wrong floating point abi used; stubs-hard.h should be included)
build/CMakeFiles/CMakeError.log
Determining if the include file pthread.h exists failed with the following output:
Change Dir: /home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/gmake cmTC_76e89/fast && /usr/bin/gmake -f CMakeFiles/cmTC_76e89.dir/build.make CMakeFiles/cmTC_76e89.dir/build
gmake[1]: Entering directory '/home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_76e89.dir/CheckIncludeFile.c.o
/usr/bin/clang -D_ARM_GCC_ -isystem /usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf -isystem /usr/arm-linux-gnueabihf/include/gnu -isystem /usr/arm-linux-gnueabihf/include -mtune=cortex-a9 -o CMakeFiles/cmTC_76e89.dir/CheckIncludeFile.c.o -c /home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeTmp/CheckIncludeFile.c
In file included from /home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:
In file included from /usr/arm-linux-gnueabihf/include/pthread.h:21:
In file included from /usr/arm-linux-gnueabihf/include/features.h:485:
/usr/arm-linux-gnueabihf/include/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-soft.h' file not found
# include <gnu/stubs-soft.h>
^~~~~~~~~~~~~~~~~~
1 error generated.
gmake[1]: *** [CMakeFiles/cmTC_76e89.dir/build.make:85: CMakeFiles/cmTC_76e89.dir/CheckIncludeFile.c.o] Error 1
gmake[1]: Leaving directory '/home/jp/sandbox/so/cmake/build/CMakeFiles/CMakeTmp'
gmake: *** [Makefile:140: cmTC_76e89/fast] Error 2
Some more Info:
I made sure the toolchain.cmake is considered (triggered a parse error to check)
$> cat toolchain.cmake CMakeLists.txt
produces the same output as the "original" CMakeLists.txt
pthread.h can be found on my System at the following locations:
$> find /usr/ -name pthread.h
/usr/arm-linux-gnueabi/include/pthread.h
/usr/arm-linux-gnueabihf/include/pthread.h
/usr/include/newlib/pthread.h /usr/include/pthread.h

As #Tsyvarev pointed out, the CMakeError.log contained useful information (the question was edited with its content).
The issue:
cmake finds pthread.h but clang cannot compile it
...
/usr/arm-linux-gnueabihf/include/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-soft.h' file not found
...
The clang invocation is interesting because of "/usr/bin/clang" (expected clang++) and no -target flag used
The solution:
Tell cmake to also use a specific -target flag for C cross-compilers supoorting it:
Add the following in target.cmake
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
(Same target as CMAKE_CXX_COMPILER_TARGET)

Related

Is it possible to call a custom CMake function when library is linked?

Let's say I have a library A and a project B which uses A.
project(libA)
function(calledWhenLink target)
message(STATUS Hi ${target}) # Should print "Hi exeB"
endfunction()
add_library(libA INTERFACE)
project(exeB)
find_package(A REQUIRED)
target_link_library(exeB libA)
Is it possible to automatically call calledWhenLink() when the executable links to the library ?
Reasoning: As said in a comment, the original problem is that VTK needs to call CMake vtk_module_autoinit. My library uses VTK, and it seems better for all the samples to automatically call this when linked to the lib instead of copy paste the code in each CMakeLists. The problem is that vtk_module_autoinit is not working when called with the lib target instead ot the exe in my tests.
Yes, it is possible to run arbitrary CMake code at build time. However, it is not at all clear what you're really trying to do, so this might not be a good approach.
Here's a minimal example:
cmake_minimum_required(VERSION 3.21)
project(example)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post-link.cmake" [[
message(STATUS "Hi ${target}")
]])
add_executable(exeB main.cpp)
add_custom_command(
TARGET exeB POST_BUILD
COMMAND "${CMAKE_COMMAND}"
-Dtarget=exeB
-P "${CMAKE_CURRENT_BINARY_DIR}/post-link.cmake"
)
Test interaction:
alex#alex-ubuntu:~/test$ cmake -G Ninja -S . -B build
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - 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: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
alex#alex-ubuntu:~/test$ cmake --build build/ --verbose
[1/2] /usr/bin/c++ -MD -MT CMakeFiles/exeB.dir/main.cpp.o -MF CMakeFiles/exeB.dir/main.cpp.o.d -o CMakeFiles/exeB.dir/main.cpp.o -c /home/alex/test/main.cpp
[2/2] : && /usr/bin/c++ CMakeFiles/exeB.dir/main.cpp.o -o exeB && cd /home/alex/test/build && /usr/bin/cmake -Dtarget=exeB -P /home/alex/test/build/post-link.cmake
-- Hi exeB

why 'target_link_libraries' command is not working? (cplex)

I tried to compile an project with cmake command(all implementation is written by other people. my job is just compile and run.)
error messages after cmake
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.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
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
fatal: bad revision 'HEAD'
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found LibXml2: /usr/lib/x86_64-linux-gnu/libxml2.so (found version "2.9.10")
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- CPLEX Library: /opt/ibm/ILOG/CPLEX_Studio1210/cplex/lib/x86-64_linux/static_pic/libcplex.a
-- ILOCPLEX Library: /opt/ibm/ILOG/CPLEX_Studio1210/cplex/lib/x86-64_linux/static_pic/libilocplex.a
-- CONCERT Library: /opt/ibm/ILOG/CPLEX_Studio1210/concert/lib/x86-64_linux/static_pic/libconcert.a
-- CPLEX Bin Dir: /opt/ibm/ILOG/CPLEX_Studio1210/cplex/bin/x86-64_linux
-- Found CPLEX: /opt/ibm/ILOG/CPLEX_Studio1210/cplex/lib/x86-64_linux/static_pic/libcplex.a
-- Configuring done
CMake Error at cpxutils/CMakeLists.txt:25 (add_executable):
Target "cpx_solver" links to target "Cplex::Cplex" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
CMake Error at cpxutils/CMakeLists.txt:13 (add_library):
Target "cpxutils" links to target "Cplex::Cplex" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
CMake Error at feaspump/CMakeLists.txt:17 (add_executable):
Target "fp2" links to target "Cplex::Cplex" but the target was not found.
Perhaps a find_package() call is missing for an IMPORTED target, or an
ALIAS target is missing?
CMake Error at feaspump/CMakeLists.txt:5 (add_library):
Target "fp" links to target "Cplex::Cplex" but the target was not found.
Perhaps a find_package() call is missing for an IMPORTED target, or an
ALIAS target is missing?
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
and this is cpxutils/CMakeLists.txt file.
cmake_minimum_required(VERSION 3.6)
# Find CPLEX library
find_package(CPLEX)
# Export CPLEX_FOUND for CMakeLists.txt files in other subdirectories
set(CPLEX_FOUND ${CPLEX_FOUND} PARENT_SCOPE)
if (CPLEX_FOUND)
# Define libcpxutils
add_library(cpxutils STATIC cpxutils.cpp cpxmacro.cpp model.cpp gomory.cpp cpxapp.cpp)
target_include_directories(cpxutils PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(cpxutils PUBLIC utils Cplex::Cplex)
add_library(Cpxutils::Lib ALIAS cpxutils)
# Define cpx_solver executable
add_executable(cpx_solver EXCLUDE_FROM_ALL cpx_solver.cpp)
target_include_directories(cpx_solver PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(cpx_solver PUBLIC utils Cpxutils::Lib)
else()
message(WARNING "Disabling CPXUTILS subproject")
endif()
i don't know why cannot find target despite CPLEX package is found.
i'm using WSL1 (Ubuntu) environment.
↑ problem solved. thanks for #Tsyvarev.
=== additional problem ===
Even though cmake commad works without any error, I cant find execution file. So I checked 'CMakeError.log' file then, there are some error.
This is CMakeError.log file.
Performing C SOURCE FILE Test CMAKE_HAVE_LIBC_PTHREAD failed with the following output:
Change Dir: /mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_92254/fast && /usr/bin/make -f CMakeFiles/cmTC_92254.dir/build.make CMakeFiles/cmTC_92254.dir/build
make[1]: Entering directory '/mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_92254.dir/src.c.o
/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -o CMakeFiles/cmTC_92254.dir/src.c.o -c /mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp/src.c
Linking C executable cmTC_92254
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_92254.dir/link.txt --verbose=1
/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD CMakeFiles/cmTC_92254.dir/src.c.o -o cmTC_92254
/usr/bin/ld: CMakeFiles/cmTC_92254.dir/src.c.o: in function `main':
src.c:(.text+0x46): undefined reference to `pthread_create'
/usr/bin/ld: src.c:(.text+0x52): undefined reference to `pthread_detach'
/usr/bin/ld: src.c:(.text+0x63): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
make[1]: *** [CMakeFiles/cmTC_92254.dir/build.make:87: cmTC_92254] Error 1
make[1]: Leaving directory '/mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp'
make: *** [Makefile:121: cmTC_92254/fast] Error 2
Source file was:
#include <pthread.h>
void* test_func(void* data)
{
return data;
}
int main(void)
{
pthread_t thread;
pthread_create(&thread, NULL, test_func, NULL);
pthread_detach(thread);
pthread_join(thread, NULL);
pthread_atfork(NULL, NULL, NULL);
pthread_exit(NULL);
return 0;
}
Determining if the function pthread_create exists in the pthreads failed with the following output:
Change Dir: /mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_8ae2b/fast && /usr/bin/make -f CMakeFiles/cmTC_8ae2b.dir/build.make CMakeFiles/cmTC_8ae2b.dir/build
make[1]: Entering directory '/mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_8ae2b.dir/CheckFunctionExists.c.o
/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_8ae2b.dir/CheckFunctionExists.c.o -c /usr/share/cmake-3.16/Modules/CheckFunctionExists.c
Linking C executable cmTC_8ae2b
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8ae2b.dir/link.txt --verbose=1
/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create CMakeFiles/cmTC_8ae2b.dir/CheckFunctionExists.c.o -o cmTC_8ae2b -lpthreads
/usr/bin/ld: cannot find -lpthreads
collect2: error: ld returned 1 exit status
make[1]: *** [CMakeFiles/cmTC_8ae2b.dir/build.make:87: cmTC_8ae2b] Error 1
make[1]: Leaving directory '/mnt/c/Users/aero5010/Desktop/CBC+FP/CBC+FP/fp2/build/CMakeFiles/CMakeTmp'
make: *** [Makefile:121: cmTC_8ae2b/fast] Error 2
I think this is why i cant find execution file. But I dont know why this error occured despite pthread library is installed well...
** thank you for every advice about Stackoverflow Manners.

CMake 3.0+Fortran+CUDA requires -fPIC even when building executables

This is a CMake question. I cannot compile Fortran executables with CUDA support when using the Intel Fortran compiler, unless I include the -fPIC flag. The problem is that -fPIC shouldn't be necessary unless I'm building a library.
The following is minimal example:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(cuda LANGUAGES Fortran CXX)
find_package(CUDA)
cuda_add_executable(main main.f90)
and
# main.f90
end
When I try to build and run,
cmake -D CMAKE_Fortran_COMPILER=ifort .. && make VERBOSE=1
I get the following:
-- The Fortran compiler identification is Intel 18.0.0.20170811
-- The CXX compiler identification is GNU 7.3.0
-- Check for working Fortran compiler: /opt/intel/compilers_and_libraries_2018.0.128/linux/bin/intel64/ifort
-- Check for working Fortran compiler: /opt/intel/compilers_and_libraries_2018.0.128/linux/bin/intel64/ifort -- works
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Checking whether /opt/intel/compilers_and_libraries_2018.0.128/linux/bin/intel64/ifort supports Fortran 90
-- Checking whether /opt/intel/compilers_and_libraries_2018.0.128/linux/bin/intel64/ifort supports Fortran 90 -- yes
-- 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
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found CUDA: /opt/cuda (found version "9.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/raul/tmp/cuda/build
/usr/bin/cmake -H/home/raul/tmp/cuda -B/home/raul/tmp/cuda/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/raul/tmp/cuda/build/CMakeFiles /home/raul/tmp/cuda/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/raul/tmp/cuda/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend
make[2]: Entering directory '/home/raul/tmp/cuda/build'
cd /home/raul/tmp/cuda/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/raul/tmp/cuda /home/raul/tmp/cuda /home/raul/tmp/cuda/build /home/raul/tmp/cuda/build /home/raul/tmp/cuda/build/CMakeFiles/main.dir/DependInfo.cmake --color=
Dependee "/home/raul/tmp/cuda/build/CMakeFiles/main.dir/DependInfo.cmake" is newer than depender "/home/raul/tmp/cuda/build/CMakeFiles/main.dir/depend.internal".
Dependee "/home/raul/tmp/cuda/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/raul/tmp/cuda/build/CMakeFiles/main.dir/depend.internal".
Scanning dependencies of target main
make[2]: Leaving directory '/home/raul/tmp/cuda/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/requires
make[2]: Entering directory '/home/raul/tmp/cuda/build'
make[2]: Nothing to be done for 'CMakeFiles/main.dir/requires'.
make[2]: Leaving directory '/home/raul/tmp/cuda/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build
make[2]: Entering directory '/home/raul/tmp/cuda/build'
[ 50%] Building Fortran object CMakeFiles/main.dir/main.f90.o
/opt/intel/compilers_and_libraries_2018.0.128/linux/bin/intel64/ifort -I/opt/cuda/include -c /home/raul/tmp/cuda/main.f90 -o CMakeFiles/main.dir/main.f90.o
[100%] Linking CXX executable main
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.f90.o -o main /opt/cuda/lib64/libcudart_static.a -lpthread -ldl -lrt -lifport -lifcoremt -limf -lsvml -lipgo -lirc -lpthread -lsvml -lirc_s -ldl
/usr/bin/ld: CMakeFiles/main.dir/main.f90.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../lib/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/bin/ld: final link failed: Invalid operation
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:97: main] Error 1
make[2]: Leaving directory '/home/raul/tmp/cuda/build'
make[1]: *** [CMakeFiles/Makefile2:69: CMakeFiles/main.dir/all] Error 2
make[1]: Leaving directory '/home/raul/tmp/cuda/build'
make: *** [Makefile:84: all] Error 2
I do not get the build error if I use the newer CUDA features of CMake, e.g.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(cuda LANGUAGES Fortran CUDA)
add_executable(main main.f90)
However, our current policy is to support CMake 3.0 and thus I cannot the simpler version. Also, I do not get any error if instead of ifort I use gfortran. I'm currently looking into FindCUDA.cmake that ships with CMake, but I haven't found a solution yet. Any thoughts?
I found a solution that works for now, but it's not trivial at all. First, one should use icpc with ifort (not a requirement for CMake >=3.8). It turns out that out of the many libraries that icpc links against under the hood (you won't see them without running make VERBOSE=1), one of them (but not others) should be linked against statically. Thus, by specifying
target_link_libraries(main ifcoremt.a)
in CMakeLists.txt seems to fix the problem, at least for me.

CMake doesn't pass CUDA arguments?

I am trying to compile a library with both, C++ and CUDA source files. I am using GNU make with CMake. My compiler of choice is clang, since CUDA only supports gcc up to version 5 and Debian 9 has gcc 6 as its oldest version and I have to use software that is provided by the Debian 9 or 10 repositories.
CMake version is 3.9.0
clang version is 3.8.1
cc and c++ in /usr/bin correctly link to clang and clang++ ẃhich also link to the correct files.
Unfortunately the initial checks of CMake for CUDA fail although everything, as far as I can see, seems to be set up correctly. It looks like the arguments aren't passed correctly to the CUDA compiler.
This is a part of my project's main CMake file:
cmake_minimum_required (VERSION 3.9.0 FATAL_ERROR)
project (dev)
find_package(CUDA REQUIRED)
set(CUDA_HOST_COMPILATION_CPP ON)
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Wno-deprecated-gpu-targets -ccbin clang-3.8")
The library's CMake file looks like this:
cmake_minimum_required(VERSION 3.9.0 FATAL_ERROR)
project (libname LANGUAGES CXX CUDA)
file(GLOB SOURCES "*.cu" "*.cpp")
add_library(libname ${SOURCES})
set_target_properties(libname PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(libname PROPERTIES POSITION_INDEPENDENT_CODE ON)
This is the output of CMake:
-- The C compiler identification is Clang 3.8.1
-- The CXX compiler identification is Clang 3.8.1
-- 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
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found CUDA: /usr (found version "8.0")
-- The CUDA compiler identification is unknown
-- Check for working CUDA compiler: /usr/bin/nvcc
-- Check for working CUDA compiler: /usr/bin/nvcc -- broken
The CUDA/nvcc tests of CMake fails with the following errors:
Change Dir: /home/user/projects/hamonIC-linux-experimental/current_state/working_copy/code/build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_6d1a9/fast"
/usr/bin/make -f CMakeFiles/cmTC_6d1a9.dir/build.make
CMakeFiles/cmTC_6d1a9.dir/build
make[1]: Entering directory
'/home/user/projects/hamonIC-linux-experimental/current_state/working_copy/code/build/CMakeFiles/CMakeTmp'
Building CUDA object CMakeFiles/cmTC_6d1a9.dir/main.cu.o
/usr/bin/nvcc -x cu -c
/home/user/projects/hamonIC-linux-experimental/current_state/working_copy/code/build/CMakeFiles/CMakeTmp/main.cu
-o CMakeFiles/cmTC_6d1a9.dir/main.cu.o
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are
deprecated, and may be removed in a future release (Use
-Wno-deprecated-gpu-targets to suppress warning).
ERROR: No supported gcc/g++ host compiler found, but clang-3.8 is
available.
Use 'nvcc -ccbin clang-3.8' to use that instead.
CMakeFiles/cmTC_6d1a9.dir/build.make:65: recipe for target
'CMakeFiles/cmTC_6d1a9.dir/main.cu.o' failed
make[1]: *** [CMakeFiles/cmTC_6d1a9.dir/main.cu.o] Error 1
make[1]: Leaving directory
'/home/user/projects/hamonIC-linux-experimental/current_state/working_copy/code/build/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_6d1a9/fast' failed
make: *** [cmTC_6d1a9/fast] Error 2
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
hic_iplibrary/source/ciccommon/CMakeLists.txt:7 (project)
The CUDA NVCC flags in CMake have to be semicolon delimited and not whitespace delimited.
Change the flags in your CMakeLists.txt to use:
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-Wno-deprecated-gpu-targets;-ccbin=clang-3.8")
and that should allow CMake to pass your flags to NVCC.

cmake: c++: error: ${CFLAGS}: No such file or directory

I'm trying to follow this cmake tutorial. But when it comes to calling cmake for the first time I get the following error:
cmake -G "Unix Makefiles" .. --debug-trycompile
debug trycompile on
-- The C compiler identification is GNU 6.3.1
-- The CXX compiler identification is unknown
-- 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++ -- broken
CMake Error at /usr/share/cmake-3.7/Modules/CMakeTestCXXCompiler.cmake:44 (message):
The C++ compiler "/usr/bin/c++" is not able to compile a simple test
program.
It fails with the following output:
Change Dir: /home/user01/code/tests/cmake_tutorial_02/build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_7a86e/fast"
/usr/bin/make -f CMakeFiles/cmTC_7a86e.dir/build.make
CMakeFiles/cmTC_7a86e.dir/build
make[1]: Entering directory
'/home/user01/code/tests/cmake_tutorial_02/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_7a86e.dir/testCXXCompiler.cxx.o
/usr/bin/c++ -march=native -O2 -pipe -fstack-protector-strong -o
CMakeFiles/cmTC_7a86e.dir/testCXXCompiler.cxx.o -c
/home/user01/code/tests/cmake_tutorial_02/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
Linking CXX executable cmTC_7a86e
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7a86e.dir/link.txt
--verbose=1
/usr/bin/c++ ${CFLAGS} CMakeFiles/cmTC_7a86e.dir/testCXXCompiler.cxx.o -o
cmTC_7a86e
c++: error: ${CFLAGS}: No such file or directory
When I call echo $CFLAGS in bash the value is:
-march=native -O2 -pipe -fstack-protector-strong
But it looks like ${CFLAGS} is not defined while executing cmake_link_script. To verify I changed ${CFLAGS} in link.txt to -march=native -O2 -pipe -fstack-protector-strong and manually called:
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7a86e.dir/link.txt
which works.
Next I tried adding the following line to CMakeLists.txt:
set (CFLAGS -O2)
which didn't help.
Neither did calling:
cmake -DCFLAGS=-O2 -G "Unix Makefiles" ..
So my question is, how to define CFLAGS so it is defined when calling the cmake_link_script in cmake's command mode?
EDIT
It looks like cmake fails withe the "Unix Makefiles" generator and doesn't even get to the code from the Tutorial.
the CMakeLists.txt just looks like this:
project("To Do List")
add_executable(toDo main.cc
ToDo.cc)
EDIT2
I found a workaround.
For some reason the generator sets CMAKE_CXX_FLAGS:STRING='${CFLAGS} ' in CMakeCache.txt.
But when the generator gets invoked with:
cmake -DCMAKE_CXX_FLAGS:STRING="${CFLAGS} " -G "Unix Makefiles" ..
everything works. Even the "The CXX compiler identification is unknown" message is gone.
However, I would still like to know why the generator failed before?