问题
Hi I am getting below error while compiling a c code using gcc
/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
I am trying to import the fftw()
function into SystemVerilog. Here is my code
#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;
}
Here is a system Verilog code from where I am trying to call fftw
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
Here is an irun command to compile both systemverilg and C files
# 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
while running this command give below error: building library run.so ld: /home/fftw/local/lib/libfftw3.a(mapflags.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /homefftw/local/lib/libfftw3.a: could not read symbols: Bad value collect2: ld returned 1 exit status make: * [/home/ss69/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so] Error 1 ncsc_run: *E,TBBLDF: Failed to build test library /home/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so
irun: *E,CCERR: Error during cc compilation (status 1), exiting.
When I simply try to compile C using gcc with below command:
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
I get this error:
/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
回答1:
Exactly how are you using the function void fftw(double FFT_in[],int size)
from your comments it sounds like you are coding routine that is called as DLL or as part of a static library.
If this is the case then adding main()
isn't going to help, at all.
What you have written is ABSOLUTELY 100% OK, if it is to be used as a callable routine.
What you might need to do is compile this routine into a library, even a static lib. is probably ok. If this is the case then consult your GCC documentation on how to create a static or dynamic lib.
Finally, I have written Verilog code myself, so you can also provide any lines or references to Verilog documentation that you have read and whose instructions you are following. I assume that at some point you are invoking Verilog and supplying it with a list of libraries it can/should use. Your lib should be included in that list.
Am including comments from jxh per his request: To import the function into SystemVerilog, you need to compile your function into a shared object. Then, you would point SystemVerilog at the shared object. (I don't use SystemVerilog, but that is what I gather from its web page.)
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
回答2:
- Your are missing
#include "svdpi.h"
in the fftwc.c file (or maybe you are not showing it because it is in fftwc.h). This include is needed for DPI. - You are compiling a DPI library to be used with a SystemVerilog simulator. Therefore, you do not need a
main()
method. - I prefer to always compile all DPI methods outside of the SystemVerilog compiler. The include the DPI library to the simulation phase. My flow looks something like the following:
${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
If you cannot get past the first gcc stage then your issue is clearly on the C side.
I do not have access to the fftw3 library at the moment. I'm wondering your void fftw(double FFT_in[],int size)
might be clobbering a library function. Try renaming it void dpi_fftw(double FFT_in[],int size)
回答3:
You have no main function. Every binary must define main. If it doesn't, you don't have a null region of memory that _start defines in the binary, which means your program can't start!
Add a function:
int main(){
fftw(doubleArgumentsArray, intArgument); //Or whatever function calls this function
return 1; //Needed for C89, C99 will automatically return 1
}
回答4:
Have found the following tutorial on Dynamic Programming Interface (DPI) :
http://www.doulos.com/knowhow/sysverilog/tutorial/dpi/
Specifically, scroll down to the "Including Foreign Language Code".
It should help with background information about how to construct a C modules for SystemVerilog.
Also, the tutorial has the following import
statement:
import "DPI" function void slave_write(input int address, input int data);
This SystemVerilog statement obviously has input
defs on the parameters, is this required? Your import
does NOT identify input vs. output??
回答5:
I believe this is an issue with some gcc linkers. I added the following linker flag:
irun ... -Wld,-B/usr/lib/x86_64-linux-gnu
And it fixed the issue.
来源:https://stackoverflow.com/questions/18086992/undefined-reference-to-main-in-c