2013-11-23 120 views
0

我有一个小C程序,我想链接到一个小Fortran程序,但得到链接器错误undefined reference to fibonacci_array无法链接小C和Fortran程序

的Fortran代码:

module fibonacci_number 
    implicit none 
    integer, parameter :: LongInt = selected_int_kind (38) 
contains 
    integer (kind=LongInt) elemental function fibonacci(ordinal) 
    implicit none 
    ! Declare variables 
    integer, intent(in) :: ordinal 
    integer :: count 
    integer (kind=LongInt), dimension(2,2) :: matrix, initial 
    matrix=reshape((/ 1, 1, 1, 0 /), shape(matrix)) 
    initial=reshape((/ 1, 0, 0, 1 /), shape(initial)) 
    count = ordinal 

    ! Do actual computations 
    do while (count > 0) 
     ! If the exponent is odd, then the output matrix 
     ! should be multiplied by the current base 
     if (mod(count,2) == 1) then 
      initial = matmul(matrix, initial) 
     end if 
     ! This is the squaring step 
     matrix = matmul(matrix, matrix) 
     count = count/2 
    end do 
    fibonacci = initial(1,2) 
    end function fibonacci 

    subroutine fibonacci_array (input, len) bind(C) 
    use, intrinsic :: ISO_C_BINDING 
    implicit none 
    integer (kind=c_int), intent(in), value :: len 
    integer (kind=c_int), dimension(len), intent(in) :: input 
    ! integer, allocatable, target :: input(:) 
    integer (kind=LongInt), allocatable :: array(:) 
    allocate (array(len)) 
    array = fibonacci(input) 
    write(*,*) array  
    end subroutine fibonacci_array 
end module fibonacci_number 

C代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

void fibonacci_array(int *ptr, int len); 

int main(int argc, char *argv[]) 
{ 
    if (argc < 2) { 
    fputs("This program calculates Fibonacci numbers corresponding to its arguments. You must enter at least one argument.\n", stderr); 
    return 1; 
    } 
    int i; 
    int *input = malloc(((size_t)argc - 1)*(sizeof(int))); 
    for (i = 0; i < argc - 1; i++) { 
    char *test = argv[i]; 
    input[i-1] = strtoll(argv[i], &test, 10); 
    if (*test != '\0') { 
     fprintf(stderr, "You must enter an integer, not '%s'\n", argv[i]); 
     return 1; 
    } 

    if (input[i-1] < 0) { 
     fputs("You must enter a positive number!\n", stderr); 
     return 1; 
    } 

    if (errno != 0 || input[i-1] > 184) { 
     fprintf(stderr, "%s is too large \n", argv[i]); 
     return 1; 
    } 
    } 

    fibonacci_array (input, argc - 1); 
    return 0; 
} 

生成文件:

# This macro contains the source files 
# D sources not included because of rdmd 
sources := $(wildcard *.c *.f08) 
include FFLAGS 
include CFLAGS 
objects := $(sources:%.c=%.o) 
objects := $(objects:%.f08=%.o) 
.SUFFIXES: 
.SUFFIXES: .f08 .c .o 
.SILENT: 
all: combined 

clean: 
    $(RM) $(objects) combined 

combined: call.o fibonacci_function.o 
    echo "Linking combined executable" 
    gcc $< -o [email protected] -L/usr/local/lib64 

.c.o: 
    echo "Building [email protected] from $<" 
    gcc $(CFLAGS) $< -c -o [email protected] 

.f08.o: 
    echo "Building [email protected] from $<" 
    gfortran $(FFLAGS) $< -c -o [email protected] 

错误消息:

Linking combined executable 
call.o: In function `main': 
call.c:(.text.startup+0x25c): undefined reference to `fibonacci_array' 
collect2: error: ld returned 1 exit status 
make: *** [combined] Error 1 
make: Target `all' not remade because of errors. 

回答

3

在make中,$<只是第一个必备条件的名称。您需要在链接命令中需要$^(所有必需品的名称),以便将call.ofibonacci.o链接到combine。 (见Automatic variables in make。)

(的$^更正错误的代表性和$<与符号,而不是在我的回答较早版本的美元符号。)

+0

咄,应该知道。我想这就是我有这么多的标志,实际的文件很难找到。 – Demi

+0

嗯,在写我的答案的第一稿时,我犯了类似的错误。符号字符太多了。 (顺便说一下,我喜欢在命令前面使用echo语句的想法,太糟糕了,您没有在链接回显中包含'$