【问题标题】:undefined reference to `gemmkernel_'--C++ routine called from Fortran对“gemmkernel_”的未定义引用——从 Fortran 调用的 C++ 例程
【发布时间】:2012-01-15 12:56:33
【问题描述】:

我一直在研究一个调用 C++ 方法的 Fortran 例程。尝试制作时出现以下错误:

make -f makefile_gcc

错误:

gfortran -O3 -o tgemm tgemm.o mytimer.o dgemmf.o -lblas -dgemmkernel.o dgemmf.o:在函数“dgemmf_”中: dgemmf.f:(.text+0x135): 对“gemmkernel_”的未定义引用 collect2: ld 返回 1 个退出状态 制作:*** [tgemm] 错误 1

这是我的生成文件:

  `FC=gfortran
    CC=gcc
    FFLAGS = -O3
    CFLAGS = -O5
    BLASF=dgemmf.o
    BLASFSRC=dgemmf.f
    TIMER=mytimer.o

    TGEMM=tgemm
    ALL= $(TGEMM)

    LIBS = -lblas -dgemmkernel.o

    all: $(ALL)

    $(TGEMM): dgemmkernel.o tgemm.o $(TIMER) $(BLASF)
        $(FC) $(FFLAGS) -o $(TGEMM) tgemm.o $(TIMER) $(BLASF) $(LIBS)

    dgemmkernel.o: dgemmkernel.cpp  
        $(CC) $(CFLAGS) -c dgemmkernel.cpp

    tgemm.o: tgemm.f $(INCLUDE)
        $(FC) $(FFLAGS) -c tgemm.f
    clean:
        rm -rf *.o $(ALL) 

这是我的 Fortran 代码:

子程序 DGEMMF(TRANSA、TRANSB、M、N、K、ALPHA、A、LDA、B、LDB、 $ 测试版,C,最不发达国家) * .. 标量参数 .. 字符*1 TRANSA, TRANSB 整数 M、N、K、LDA、LDB、LDC 双精度 Alpha、Beta * .. 数组参数 .. 双精度 A( LDA, * ), B( LDB, * ), C( LDC, * ) * .. 外部函数 .. 逻辑 LSAME 外部 LSAME * .. 局部标量 .. 逻辑注释,NOTB 整数 I, J, L * .. 参数 .. 双精度一,零 参数(一 = 1.0D+0,零 = 0.0D+0) * .. * .. 可执行语句 .. * * 如果 A 和 B 分别没有转置,则将 NOTA 和 NOTB 设置为 true * NOTA = LSAME(TRANSA, 'N' ) NOTB = LSAME(TRANSB, 'N' ) * * 我们只想要 C = A°B * IF ((ALPHA.NE.ONE).OR.(BETA.NE.ZERO).OR. $ (.NOT.NOTA).OR.(.NOT.NOTB)) 停止 * * 开始操作。 调用 gemmkernel(M、N、K、A、LDA、B、LDB、C、LDC) 返回 * DGEMM 结束。 * 结尾

这是我试图调用的 C++ 位

 void gemmkernel_(int * M, int * N, int * K,
                    double * a, int * LDA, 
                    double * b, int * LDB,
                    double * c, int * LDC) 

确实会创建所有 .o 文件,但可执行文件从未完成。我怀疑错误出在我的 makefile 上,因为到目前为止我发现的每个来源都向我表明我的 Fortran/C++ 代码是正确的。

【问题讨论】:

  • LIBS = -lblas -dgemmkernel.o 这看起来很可疑;你确定破折号应该在dgemmkernel.o之前出现吗?
  • 您可能会从 C++ 编译器中遇到名称修改,并且目标文件中没有 gemmkernel_,而是类似 __Z10gemmkernelPiS_S_PdS_S0_S_S0_S_

标签: c++ reference fortran undefined


【解决方案1】:

您的制作在链接时失败。 dgemmkernel.o 应该在目标文件列表中。我假设你想要这条线:

$(FC) $(FFLAGS) -o $(TGEMM) tgemm.o $(TIMER) $(BLASF) $(LIBS)

成为:

$(FC) $(FFLAGS) -o $(TGEMM) tgemm.o dgemmkernel.o $(TIMER) $(BLASF) $(LIBS)

LIBS = -lblas -dgemmkernel.o    

成为:

LIBS = -lblas

【讨论】:

  • 感谢您的回答。我试过了,但我仍然遇到同样的错误。关于问题可能出在哪里的任何其他想法?
  • dgemmf.o 来自哪里?我没有看到它正在你的 makefile 中编译。
  • 我想通了。 .cpp 文件需要重命名为 .c
猜你喜欢
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 2012-01-02
  • 1970-01-01
  • 2016-03-09
相关资源
最近更新 更多