【问题标题】:undefined reference to `main' in C在 C 中未定义的对“main”的引用
【发布时间】:2023-03-08 09:45:01
【问题描述】:

您好,我在使用 gcc 编译 c 代码时遇到错误

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

我正在尝试将fftw() 函数导入SystemVerilog。这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <fftw3.h> 

void fftw(double FFT_in[],int size)
{

    double *IFFT_out;
    int i;

    fftw_complex *middle;

    fftw_plan fft;
    fftw_plan ifft;
    middle = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
    IFFT_out = (double *) malloc(size*sizeof(double));

    fft = fftw_plan_dft_r2c_1d(size, FFT_in, middle, FFTW_ESTIMATE);  //Setup fftw plan for fft (real 1D data)
    ifft = fftw_plan_dft_c2r_1d(size, middle, IFFT_out, FFTW_ESTIMATE);   //Setup fftw plan for ifft

    fftw_execute(fft);
    fftw_execute(ifft);

    printf("Input:    \tFFT_coefficient[i][0]      \tFFT_coefficient[i][1]   \tRecovered Output:\n");

    for(i=0;i<size;i++)
        printf("%f\t%f\t\t\t%f\t\t\t%f\n",FFT_in[i],middle[i][0],middle[i][1],IFFT_out[i]/size);

    fftw_destroy_plan(fft);
    fftw_destroy_plan(ifft);
    fftw_free(middle);
    free(IFFT_out);

    //return IFFT_out;
}

这是我试图调用 fftw 的系统 Verilog 代码

module top;
import "DPI-C" function void fftw(real FFT_in[0:11], int size);
real j [0:11];
integer i,size;
real FFT_in [0:11]; 

initial begin
    size = 12;
    FFT_in[0] = 0.1;
     FFT_in[1] = 0.6;
     FFT_in[2] = 0.1;
     FFT_in[3] = 0.4;
     FFT_in[4] = 0.5;
     FFT_in[5] = 0.0;
     FFT_in[6] = 0.8;
     FFT_in[7] = 0.7;
     FFT_in[8] = 0.8;
     FFT_in[9] = 0.6;
     FFT_in[10] = 0.1;
     FFT_in[11] = 0.0;

    $display("Entering in SystemVerilog Initial Block\n");
    #20
     fftw(FFT_in,size);

    $display("Printing recovered output from system verilog\n"); 
    //for(i=0;i<size;i++)
        //$display("%f\t\n",(j[i])/size);

    $display("Exiting from SystemVerilog Initial Block");
    #5 $finish;

end

endmodule

这是一个 irun 命令来编译 systemverilg 和 C 文件

# Compile the SystemVerilog files
fftw_test.sv 
-access +rwc
# Generate a header file called _sv_export.h
-dpiheader _sv_export.h
# Delay compilation of fftw_test.c until after elaboration
#-cpost fftw_test_DPI.c -end
-I/home/fftw/local/include -L/home/ss69/fftw/local/lib fftw_test_DPI.c -lfftw3 -lm 
# Redirect output of ncsc_run to a log file called ncsc_run.log
-log_ncsc_run ncsc_run.log

运行此命令时出现以下错误: 构建库 run.so ld: /home/fftw/local/lib/libfftw3.a(mapflags.o): 重定位 R_X86_64_32 反对 `.rodata' 在制作共享对象时不能使用;使用 -fPIC 重新编译 /homefftw/local/lib/libfftw3.a:无法读取符号:错误值 collect2: ld 返回 1 个退出状态 make: * [/home/ss69/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so] 错误1 ncsc_run: *E,TBBLDF: 构建测试库失败 /home/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so

irun: *E,CCERR: cc 编译时出错(状态1),正在退出。

当我尝试使用 gcc 和以下命令编译 C 时:
gcc -g -Wall -Werror -I/home/fftw/local/include -L/home/ss69/fftw/local/lib \ fftw_test_DPI.c -lfftw3 -lm -o fftw_test_DPI

我收到此错误:

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/crt1.o:在函数_start': (.text+0x20): undefined reference tomain' collect2: ld 返回 1 个退出状态

【问题讨论】:

  • 你有main函数吗?
  • “我没有主函数,但链接器告诉我没有主函数...” - welcome to the Tautology Club.
  • 也许你只想编译,而不是链接 (-c)
  • @H2CO3 为什么不花点时间了解一下用户呢?大多数人的方法都是诚实的,并且从他们的角度来看,他们提出了一个有效的问题。
  • @Sandeep - 根据您的问题和答案中的评论,我认为您需要阅读一本基本的 C 书籍来了解 C 程序是如何组合在一起的。您遗漏了一些非常基本的概念。

标签: c gcc system-verilog fftw system-verilog-dpi


【解决方案1】:

您是如何使用 cmets 中的函数 void fftw(double FFT_in[],int size) 的,听起来您正在编写称为 DLL 或作为静态库一部分的例程。

如果是这种情况,那么添加 main() 根本没有帮助。

如果要用作可调用例程,您所写的内容绝对 100% OK。

您可能需要做的是将此例程编译为库,甚至是静态库。可能没问题。如果是这种情况,请查阅您的 GCC 文档以了解如何创建静态或动态库。

最后,我自己编写了 Verilog 代码,因此您还可以提供对您已阅读并遵循其说明的 Verilog 文档的任何行或参考。我假设在某些时候您正在调用 Verilog 并为其提供可以/应该使用的库列表。您的库应该包含在该列表中。

根据他的要求,我包括来自 jxh 的 cmets: 要将函数导入 SystemVerilog,您需要将函数编译为共享对象。然后,您将 SystemVerilog 指向共享对象。 (我不使用 SystemVerilog,但这是我从它的网页上收集到的。)

gcc -shared -fPIC -g -Wall -Werror \
-I/home/ss69/fftw/local/include -L/home/ss69/fftw/local/lib \
fftw_test_DPI.c -lfftw3 -lm -o libfftw_test_DPI.so

【讨论】:

  • 请在我的帖子中提取一些相关信息并将其合并到您自己的帖子中。我会删除我的帖子。
  • 感谢@JackCColeman、Michael 和 jxh 我在第一篇文章中也更新了我的系统 verilog 代码。我还有一个运行文件来使用 irun 命令运行系统 verilog 和 C。我既不能只使用 gcc 编译 C 代码,也不能使用 irun 编译两个代码..
【解决方案2】:
  • 您在 fftwc.c 文件中缺少 #include "svdpi.h"(或者您可能没有显示它,因为它在 fftwc.h 中)。 DPI 需要此包含。
  • 您正在编译要与 SystemVerilog 模拟器一起使用的 DPI 库。因此,您不需要main() 方法。
  • 我更喜欢总是在 SystemVerilog 编译器之外编译所有 DPI 方法。将 DPI 库包含到仿真阶段。我的流程如下所示:
${SVTOOL} -compile -f svfiles.f -dpi_header gen_dpi_header.h
gcc -fPIC -pipe -O2 -c -g \
    -I${SVTOOL_PATH}/include -Imy_dpi_dir -I. \
    -o fftw_test_DPI.o \
    fftw_test_DPI.c
gcc -shared -o libdpi.so \
    fftw_test_DPI.o [other object files]
# then call ${SVTOOL} again for simulation with libdpi.so

如果您无法通过第一个 gcc 阶段,那么您的问题显然是在 C 方面。

目前我无法访问 fftw3 库。我想知道您的 void fftw(double FFT_in[],int size) 可能正在破坏库函数。尝试重命名void dpi_fftw(double FFT_in[],int size)

【讨论】:

  • 我可以成功执行您的三个步骤.. 但我有几个问题,gcc -O2 和 -pipe 选项有什么作用?还可以详细说明最后一步吗? # 然后再次调用 ${SVTOOL} 以使用 libdpi.so 进行模拟
  • '-O2' 是 2 级优化器。 '-pipe' 使用管道而不是临时文件在编译的各个阶段之间进行通信。这些选项给了我最好的结果(可能不是必需的)。最后一步在模拟器之间是不同的。在这个阶段,模拟器需要知道运行什么二进制文件或需要一个中间链接器阶段。您需要查看特定模拟器的工作方式。 '-sv_lib' 和 '-sv_root' 似乎是在模拟器之间包含 DPI 库的常见模拟器选项。 (doulos.com/knowhow/sysverilog/tutorial/dpi)
  • @Sandeep ,我刚刚注意到您的错误是指 lib64。如果您运行的是 64 位模拟器,则在编译阶段将“-m64”添加到 gcc。如果您的模拟器是运行 64 位机器的 32 位模拟器,那么您可能希望使用“-m32”。
  • 我在编译时添加了 -m64 选项。我正在使用 irun 来模拟 systemverilog。 irun 使用 ncsim 来模拟 systemverilog。所以在创建共享库之后,我尝试使用“irun -snshlib libdpi.so”对其进行模拟,但出现错误,它无法识别 fftw 函数。下面是完整的错误消息: irun: *E,SNLDLIB: Unableable加载动态库/home/ss69/DPI/libdpi.so。 rundynlib - 无法加载提供的库 /home/ss69/DPI/libdpi.so OS MSG:/home/ss69/DPI/libdpi.so:未定义符号:fftw_plan_dft_r2c_1d
  • 试过了," irun -sv_lib libdpi.so fftw_test.sv" 仍然导致错误:Loading snapshot worklib.top:sv .... ... Done ncsim> source /home/netcad/cadence/INCISIV12.20.010/tools/inca/files/ncsimrc ncsim> run 进入 SystemVerilog Initial Block
【解决方案3】:

你没有主函数。每个二进制文件都必须定义 main。如果没有,则说明您没有 _start 在二进制文件中定义的空内存区域,这意味着您的程序无法启动!

添加功能:

int main(){

   fftw(doubleArgumentsArray, intArgument); //Or whatever function calls this function
   return 1; //Needed for C89, C99 will automatically return 1
}

【讨论】:

  • "如果没有,则二进制文件中没有 _start 标签" - 你仍然有(在使用 _start 作为入口点的实现上),只是它有对main() 的未解决引用。
  • 我添加了 int main(){} 但仍然低于错误 cc1:警告被视为错误 fftw_test_DPI.c:在函数'main'中:fftw_test_DPI.c:7:错误:控制达到非空函数结束。实际上我是从系统verilog调用fftw,所以我不想再从main调用它。
  • @Sandeep:我不确定“从系统 verilog 调用 fftw”到底涉及什么,但听起来您可能真的想构建一个库(共享库,我'd guess) 而不是一个独立的程序。
【解决方案4】:

找到以下关于动态编程接口 (DPI) 的教程:

    http://www.doulos.com/knowhow/sysverilog/tutorial/dpi/

具体来说,向下滚动到“包括外语代码”。

它应该有助于提供有关如何为 SystemVerilog 构建 C 模块的背景信息。

此外,本教程有以下import 声明:

  import "DPI" function void slave_write(input int address, input int data);

这个SystemVerilog语句明明参数上有inputdefs,这是必须的吗?你的import 不能识别输入和输出??

【讨论】:

  • @Greg,我已经包含了#include "svdpi.h",但是当我尝试使用 gcc 在系统 verilog 之外编译 C 文件时,它给了我一个错误,fftw_test_DPI.c:6:20:错误:svdpi.h:没有这样的文件或目录..当我在 irun(sv 工具)中编译时这不是问题
  • 我有一些不使用输入关键字的示例 DPI 代码,它仍然有效。我不认为它是必需的,但是将它包含在您的代码中很好..
  • @Greg,实际上我在 svtool 安装路径中找到了 svdpi.h 的位置。使用 -I 选项指向 svdpi.h 解决了该问题。
【解决方案5】:

我相信这是一些 gcc 链接器的问题。我添加了以下链接器标志:

irun ... -Wld,-B/usr/lib/x86_64-linux-gnu

它解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多