简体   繁体   English

CMake:针对静态C库链接Fortran失败

[英]CMake: Linking Fortran against static C library fails

Using CMake and GCC to build a very basic Fortran project with an iso_c_binding fails at linking stage. 在链接阶段,使用CMake和GCC构建具有iso_c_binding的非常基本的Fortran项目失败。 Compiling and linking manually just works fine: 手动编译和链接可以正常工作:

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

The minimal CMakeLists.txt : 最小的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)

Building the project leads to the following linker error: 构建项目会导致以下链接器错误:

[...]
[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

The linker seems to search for a main() function, that Fortran does not feature. 链接器似乎在搜索main()函数,而Fortran没有此功能。 Trying to force the Fortran linker makes no difference: 尝试强制使用Fortran链接器没有区别:

set(CMAKE_Fortran_LINKER_PREFERENCE 100)
set(CMAKE_C_LINKER_PREFERENCE_PROPAGATES False)

Help is appreciated. 感谢帮助。

Example Code 范例程式码

The linker error does not depend on the actual implementation. 链接器错误不取决于实际的实现。 Anyway, a basic example would be: 无论如何,一个基本的例子是:

key.f08 : 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

And the getkey.c : getkey.c

int get_key()
{
    return 10000;
}

Verbose Make 详细制作

Running make VERBOSE=1 : 运行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

As you can see from the verbose make output: 从详细的make输出中可以看到:

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

You are not building with the Fortran code at all! 您根本不使用Fortran代码进行构建! This is because CMake doesn't recognize .f08 as a code extension. 这是因为CMake无法将.f08识别为代码扩展名。 See here: cmake, fortran 2008, and .f08 file extension 参见此处: cmake,fortran 2008和.f08文件扩展名

You may simply rename your .f08 file to .f (or .f90 as described in comments below). 您可以简单地将.f08文件重命名为.f (或.f90 ,如以下注释中所述)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM