CMake:将 Fortran 链接到静态 C 库失败

标签 c cmake linker fortran linker-errors

使用 CMake 和 GCC 构建具有 iso_c_binding 的非常基本的 Fortran 项目在链接阶段失败。手动编译和链接工作正常:

$ gcc6 -c getkey.c
$ gfortran6 -Wl,-rpath=/usr/local/lib/gcc6/ -o key key.f08 getkey.o

最小的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.9)
project(GetKey)
set(VERSION 1.0)

set(CMAKE_Fortran_COMPILER "gfortran6")
set(GCC_LIB "-Wl,-rpath=/usr/local/lib/gcc6")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${GCC_LIB}")
enable_language(Fortran)

add_library(getkey STATIC getkey.c)
add_executable(key key.f08)

set_target_properties(key PROPERTIES LINKER_LANGUAGE Fortran)
target_link_libraries(key getkey)

构建项目导致以下链接器错误:

[...]
[100%] Linking Fortran executable key
/usr/lib/crt1.o: In function `_start':
/usr/src/lib/csu/amd64/crt1.c:(.text+0x17b): undefined reference to `main'
collect2: error: ld returned 1 exit status

链接器似乎在搜索 Fortran 没有的 main() 函数。尝试强制 Fortran 链接器没有任何区别:

set(CMAKE_Fortran_LINKER_PREFERENCE 100)
set(CMAKE_C_LINKER_PREFERENCE_PROPAGATES False)

感谢您的帮助。

示例代码

链接器错误不依赖于实际实现。无论如何,一个基本的例子是:

key.f08:

program main
    implicit none

    interface
        function get_key() bind(c, name='get_key')
            use iso_c_binding
            integer(kind=c_int) :: get_key
        end function get_key
    end interface

    write(*, '(i0)') get_key()
end program main

getkey.c:

int get_key()
{
    return 10000;
}

详细制作

运行 make VERBOSE=1:

/usr/local/bin/cmake -H"/home/user/fortran" -B"/home/user/fortran" --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/bin/cmake -E cmake_progress_start "/home/user/fortran/CMakeFiles" "/home/user/fortran/CMakeFiles/progress.marks"
make -f CMakeFiles/Makefile2 all
make -f CMakeFiles/key.dir/build.make CMakeFiles/key.dir/depend
cd "/home/user/fortran" && /usr/local/bin/cmake -E cmake_depends "Unix Makefiles" "/home/user/fortran" "/home/user/fortran" "/home/user/fortran" "/home/user/fortran" "/home/user/fortran/CMakeFiles/key.dir/DependInfo.cmake" --color=
make -f CMakeFiles/key.dir/build.make CMakeFiles/key.dir/build
[ 50%] Linking Fortran executable key
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/key.dir/link.txt --verbose=1
/usr/local/bin/gfortran6    CMakeFiles/key.dir/getkey.c.o  -o key
/usr/lib/crt1.o: In function `_start':
/usr/src/lib/csu/amd64/crt1.c:(.text+0x17b): undefined reference to `main'
collect2: error: ld returned 1 exit status
*** Error code 1

Stop.
make[2]: stopped in /usr/home/user/fortran
*** Error code 1

Stop.
make[1]: stopped in /usr/home/user/fortran
*** Error code 1

Stop.
make: stopped in /usr/home/user/fortran

最佳答案

从详细的 make 输出中可以看出:

/usr/local/bin/gfortran6    CMakeFiles/key.dir/getkey.c.o  -o key

您根本没有使用 Fortran 代码进行构建!这是因为 CMake 无法将 .f08 识别为代码扩展名。看这里:cmake, fortran 2008, and .f08 file extension

您可以简单地将您的 .f08 文件重命名为 .f(或 .f90,如下面的评论所述)。

关于CMake:将 Fortran 链接到静态 C 库失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47957255/

相关文章:

c++ - shark3.0 的 "BOOST_DIR NOT FOUND"在 win7 x64 操作系统下使用 boost1.54.0 和 cmake

c++ - 如何将标准库静态链接到我的 C++ 程序?

c++ - 不使用额外空间的回文

编译器优化,线程安全?

c++ - 如何指定指向参数数量未知的 C 函数的 C++ 指针?

qt - CMake 中 QMake 的 CONFIG+=console

c - 64 位操作有时会失败

c++ - OpenCV_FOUND 为 FALSE,因此包 "OpenCV"被认为未找到

c++ - 运算符重载对某些东西不起作用,对其他东西有效....链接器错误 LNK2019

gcc - gcc/ld 如何找到 zlib.so?