即使在构建可执行文件时,CMake 3.0 + Fortran + CUDA也需要-fPIC
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了即使在构建可执行文件时,CMake 3.0 + Fortran + CUDA也需要-fPIC相关的知识,希望对你有一定的参考价值。
这是一个CMake问题。除非我包含-fPIC
标志,否则在使用Intel Fortran编译器时,我无法使用CUDA支持编译Fortran可执行文件。问题是除非我正在建立一个图书馆,否则-fPIC
不应该是必要的。
以下是最小的例子:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(cuda LANGUAGES Fortran CXX)
find_package(CUDA)
cuda_add_executable(main main.f90)
和
# main.f90
end
当我尝试构建和运行时,
cmake -D CMAKE_Fortran_COMPILER=ifort .. && make VERBOSE=1
我得到以下内容:
-- 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
如果我使用CMake的较新的CUDA功能,例如,我没有得到构建错误。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(cuda LANGUAGES Fortran CUDA)
add_executable(main main.f90)
但是,我们目前的政策是支持CMake 3.0,因此我不能使用更简单的版本。此外,如果我使用ifort
代替gfortran
,我不会得到任何错误。我目前正在研究CMake附带的FindCUDA.cmake,但我还没有找到解决方案。有什么想法吗?
答案
我找到了一个现在有效的解决方案,但它根本不是微不足道的。首先,应该使用ifp的icpc(不要求CMake> = 3.8)。事实证明,在icpc链接的许多库中(如果没有运行make VERBOSE=1
,你将看不到它们),其中一个(但不是其他)应该与静态链接。因此,通过指定
target_link_libraries(main ifcoremt.a)
在CMakeLists.txt似乎解决了这个问题,至少对我而言。
以上是关于即使在构建可执行文件时,CMake 3.0 + Fortran + CUDA也需要-fPIC的主要内容,如果未能解决你的问题,请参考以下文章