使用 ifort/icc 时未定义对“main”的引用

Posted

技术标签:

【中文标题】使用 ifort/icc 时未定义对“main”的引用【英文标题】:Undefined reference to 'main' when using ifort/icc 【发布时间】:2015-05-08 06:49:04 【问题描述】:

我正在尝试编译用 Fortran 编写的代码,然后通过 C 编译器链接。当我尝试英特尔编译器 ifort + icc 时,问题就来了。如果我对 GNU 编译器 gfortran + gcc 做同样的事情,它就可以工作。

我们可以看到他们的输出。

ICC,工作:

ifort -c -o fonts/pgpack.o -g -fno-automatic -fPIC fonts/pgpack.f ifort:命令行警告 #10006:忽略未知选项“-fno-automatic” icc -o pgpack 字体/pgpack.o -O2 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L /opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt /intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 /-L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4。 7/../../../../lib64/ -L/lib/../lib64 -L/lib/../lib64/ -L/usr/lib/../lib64 -L/usr /lib/../lib64/ -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64/ -L/ opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/g cc4.4/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../ -L/lib64 -L/lib/ -L/usr/lib64 -L/ usr/lib -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080 /ipp/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb /lib/intel64/gcc4.4 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/ -L/usr/lib/ gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../ ../../lib64/ -L/lib/../lib64 -L/lib/../lib64/ -L/usr/lib/../lib64 -L/usr/lib/../lib64/ -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64/ -L/opt/intel/composer_xe_2013_sp1.0.080/ ipp/lib/intel64/-L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/inte l64/ -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4/ -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../.. / -L/lib64 -L/lib/ -L/usr/lib64 -L/usr/lib -lifport -lifcore -limf -lsvml -lm -lipgo -lirc -lpthread -lsvml -lc -lgcc -lgcc_s -lirc_s -ldl -lc /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o:在函数'_start'中: (.text+0x20): 对 `main' 的未定义引用

注意:我很奇怪 icc 链接到 gcc 库 (/usr/lib/gcc/...)。这正常/正确吗?

GCC,正在工作:

gfortran -c -o fonts/pgpack.o -O2 -Wall -fno-second-underscore -g -fno-automatic -fPIC fonts/pgpack.f 警告:第 15 行第 6 列中的制表符不符合要求 警告:第 16 行第 6 列中的制表符不符合要求 警告:第 17 行第 6 列中的不合格制表符 警告:第 19 行第 2 列中的制表符不符合要求 警告:第 20 行第 2 列中的制表符不符合要求 警告:第 21 行第 2 列中的制表符不符合要求 警告:第 24 行第 2 列中的制表符不符合要求 警告:第 25 行第 2 列中的制表符不符合要求 gcc -o pgpack 字体/pgpack.o -O2 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/ usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 - L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/../compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib /intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64 /gcc4.4 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../.. -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 - L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64 - L/lib/../lib64 -L/usr/lib/../lib64 -L/opt/intel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/.. /compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/ipp/lib/intel64 -L/opt/in tel/composer_xe_2013_sp1.0.080/compiler/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -L/opt/intel/composer_xe_2013_sp1.0.080/tbb/lib/intel64/gcc4.4 -L/ usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../.. -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc : pgpack

我注意到一些被链接的库发生了变化(例如,libgfortranbegin),但这是由 make 系统自动添加/更改的。

对于类似的错误,我已经尝试过其他帖子提供的解决方案,例如使用标志 (ifort)-nofor-main 和 (icc)-nostartfiles,但总是失败。

我错过了什么? 谢谢。

【问题讨论】:

我不是 Fortran 编码器,但问题是 ifort 在编译 fonts/pgpack.f 时不会导出拼写为“main”的符号。尝试运行nm fonts/pgpack.o,看看里面是否有类似于'main'的东西(你可以粘贴输出)。例如,如果 icc 使用不同的符号命名约定,这可能是 C 与 C++ 的问题。在 C++ 中,这将通过 extern "C" <declarations> 解决。 你真的应该链接到编译主程序的任何东西。 开始,两种方法都显示警告。警告需要纠正,而不是忽视!不同的编译器有不同的参数,所以复制参数不是正确的方法。对于 gcc,还应该有 -Wextra 和 -pedantic,可能类似于:-std=c99 查看“icc”的参数列表很明显(由于库路径和编译器“应该”已经知道的库路径的多次重复,并且'../../../' 库路径中的各种序列,OP 需要阅读编译器的文档。 @user3629249,您抱怨的路径格式(以及路径数量)很可能来自自动化,可能是 Autoconf configure 脚本。它本质上并不是滥用甚至不知情使用的迹象。然而,可疑的是,icc 版本似乎指向 Intel 和 GNU 库目录。 【参考方案1】:

icc 的情况下,您要链接的模块都没有提供函数main() 作为程序的入口点。 gcc 仍然成功链接该程序可能部分是由于在链接中包含-lgfortranbegin。这将提供一个标准(对于gfortranmain() 函数,该函数在将控制权移交给与PROGRAM 中定义的PROGRAM 子单元相对应的不同名称的例程之前设置Fortran 环境@。

很可能通过iccifort 编译的目标文件链接到一个完整的程序中,但显然您需要一个ifort 特定的起点例程,而您指定的库都没有提供。无论如何,您在icc 链接中包含GCC 库可能是错误的。我认为您的构建系统正在识别并包含这些,但这样做是不正确的。

无论如何,当您只有一个从 Fortran 源派生的目标文件时,您与 gcc / icc 链接是非常奇怪的。您应该使用 Fortran 链接器驱动程序进行链接,这两种情况下都与 Fortran 编译器驱动程序 (gfortran / ifort) 相同。在这种情况下,您可能不需要任何您当前指定的-L-l 选项。

即使您也在某些 C 例程中进行链接,通常您也应该使用编写主例程所用语言的链接器驱动程序。有一些注意事项,如果您将一些其他语言(例如 C++)混合使用,它会变得更加复杂,但您的特定情况看起来非常简单。

【讨论】:

libgfortranbegin 是一个遗留的向后兼容的东西。在最新版本的 GCC 中没有使用它。 @VladimirF,也许是这样,但 libgfortranbegin 仍然与 OP 似乎正在使用的 GCC 4.4.7 相关。我碰巧能够直接验证。

以上是关于使用 ifort/icc 时未定义对“main”的引用的主要内容,如果未能解决你的问题,请参考以下文章

重载 cout 时未定义的引用

链接时未定义的参考错误 - Makefile 并包含已配置

在 Android 中调用 OpenCL 函数时未定义的引用

选项卡不活动时未定义的元素

exit.c:(.text+0x18): 使用 arm-none-eabi-gcc 时未定义对 `_exit' 的引用

与共享库链接时未定义的引用