我正在尝试在IBM BlueGene机器上使用CMake编译Fortran程序。这是我的来源:
> tree
.
├── CMakeLists.txt
└── src
└── test1.f90
其中test1.f90只是:
program main
use mpi
integer :: me, ierr
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, me, ierr)
write (*,"(I4,A)") me, ": hello"
call MPI_Finalize(ierr)
end program main
我想创建 静态 可执行文件。因此我创建了这个CMakeLists.txt:
cmake_minimum_required(VERSION 2.5)
project(STB)
file(GLOB_RECURSE sources src/*.f90)
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBRARIES OFF)
SET(CMAKE_EXE_LINKER_FLAGS "-static")
add_executable(test.x ${sources})
enable_language(Fortran)
set(CMAKE_Fortran_COMPILER_ID "IBM")
if(CMAKE_Fortran_COMPILER_ID MATCHES "IBM")
MESSAGE(STATUS "IBM")
set(CMAKE_Fortran_COMPILER mpixlf2008)
set(dialect "-O2 -qarch=qp -qtune=qp -ufmt_littleendian={23}")
set(debug "-C")
endif()
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${bounds}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialect}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
MESSAGE( STATUS "cmake_module_path: " ${CMAKE_MODULE_PATH})
这导致:
make VERBOSE=1
/usr/bin/cmake -H/work/jias12/jias1217/test -B/work/jias12/jias1217/test --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /work/jias12/jias1217/test/CMakeFiles /work/jias12/jias1217/test/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/work/jias12/jias1217/test'
make -f CMakeFiles/test.x.dir/build.make CMakeFiles/test.x.dir/depend
make[2]: Entering directory `/work/jias12/jias1217/test'
cd /work/jias12/jias1217/test && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /work/jias12/jias1217/test /work/jias12/jias1217/test /work/jias12/jias1217/test /work/jias12/jias1217/test /work/jias12/jias1217/test/CMakeFiles/test.x.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/work/jias12/jias1217/test'
make -f CMakeFiles/test.x.dir/build.make CMakeFiles/test.x.dir/requires
make[2]: Entering directory `/work/jias12/jias1217/test'
make[2]: Nothing to be done for `CMakeFiles/test.x.dir/requires'.
make[2]: Leaving directory `/work/jias12/jias1217/test'
make -f CMakeFiles/test.x.dir/build.make CMakeFiles/test.x.dir/build
make[2]: Entering directory `/work/jias12/jias1217/test'
/usr/bin/cmake -E cmake_progress_report /work/jias12/jias1217/test/CMakeFiles 1
[100%] Building Fortran object CMakeFiles/test.x.dir/src/test1.o
mpixlf2008 -O2 -qarch=qp -qtune=qp -ufmt_littleendian={23} -c /work/jias12/jias1217/test/src/test1.f90 -o CMakeFiles/test.x.dir/src/test1.o
** main === End of Compilation 1 ===
1501-510 Compilation successful for file test1.f90.
Linking Fortran executable test.x
/usr/bin/cmake -E cmake_link_script CMakeFiles/test.x.dir/link.txt --verbose=1
mpixlf2008 -static -O2 -qarch=qp -qtune=qp -ufmt_littleendian={23} CMakeFiles/test.x.dir/src/test1.o -o test.x -rdynamic
/opt/ibmcmp/xlf/bg/14.1/bin/.orig/bgxlf2008: 1501-210 (S) command option ynamic contains an incorrect subargument
make[2]: *** [test.x] Error 40
make[2]: Leaving directory `/work/jias12/jias1217/test'
make[1]: *** [CMakeFiles/test.x.dir/all] Error 2
make[1]: Leaving directory `/work/jias12/jias1217/test'
make: *** [all] Error 2
如果我在没有-rdynamic
的情况下重新运行最后一个参数mpixlf2008 -static -O2 -qarch=qp -qtune=qp -ufmt_littleendian={23} CMakeFiles/test.x.dir/src/test1.o -o test.x
我收到错误:
/bgsys/drivers/ppcfloor/gnu-linux/powerpc64-bgq-linux/bin/ld: -f may not be used without -shared
如何使用CMake静态编译我的程序?如果我只是跑:
mpixlf2008 -c src/test1.f90
mpixlf2008 test1.o -o bla.x
编译工作正常,大小(45M)表明,它是静态编译的。
修改
如果我删除小端标志:
set(dialect "-O2 -qarch=qp -qtune=qp")
我可以运行cmake创建的makefile,然后手动删除-rdynamic
mpixlf2008 -static -O2 -qarch=qp -qtune=qp CMakeFiles/test.x.dir/src/test1.o -o test.x
然后成功编译。如何从CMake Makefile中删除-rdynamic?
答案 0 :(得分:2)
尝试将-qstaticlink添加到链接行,而不是直接添加-static / -rdynamic。当您使用mpixlf2008命令时,编译器会在其自己的库中插入自己的-static / -rdynamic选项以进行链接,因此您添加的选项可能会干扰编译器正在使用的选项。 -qstaticlink选项告诉编译器您需要一个完全静态的二进制文件。该选项还有子选项,允许您仅静态链接gcc库。
此外,您获得的具体错误是因为您指定了" -rdynamic"。 XLF不知道这个选项,所以它假设它是一组较小的选项。因此它将其解析为:" -r -d -ynamic"。 -r用于创建不可执行的输出文件,-d用于保存预处理的输出,-y用于指定编译时舍入模式。 -y选项采用舍入模式的子选项,例如: -yn是最近的。你得到的错误是namic不是-y的已知子选项。要将-rdynamic传递给链接器,请将-Wl放在它之前。即" -Wl,-rdynamic"。
答案 1 :(得分:0)
添加
SFMyNTY.g3QAAAACZAAEZGF0YWIAAAsMZAAGc2lnbmVkbgYASDp-jVwB.HqUsytlpKq7h9qEQyjABS1Xv4sgwNFClB-asLYUGfyA
允许我删除'-rdynamic'。这可能有点手动,但对于较旧的CMake版本,它可以工作。