我有一个C-Code,用一些Linux Derivation编写,我想把它移植到Windows中。
我对Makefile做了一些修改,并使用mingw32-make来编译它们。
生成的执行文件工作正常,直到我看到结果
该程序用于进行一些数据分析,并且应该产生一个介于20和100之间的数字列表。对于一个示例数据,应该有大约48.442的3个数字。
但是,当我运行Windows可执行文件时,我得到3个数字大约292136359165898530000000000000000000000000000.000
然后我安装了virtualbox并尝试使用“make”作为console-command运行原始的Makefile,但它抱怨说,虽然插入了-lm,但是没有请求math-libary(pow undefined等)。每个gcc命令。
windows Makefile:
COMPILER_OPT = -O3
all: extract_timestamps
extract_timestamps: extract_timestamps.c collection.o filename_treatment.o basic_analysis.o read_lecroy_file.o read_tek_file.o stamp_handling.o treat_lecroy_file.o treat_tek_file.o save_timestamps.o injection_statistics.o calc_time_stamp.o peak_finding.o get_timestamps.o time_ext.h -lm
gcc -lm -o extract_timestamps.exe basic_analysis.c calc_time_stamp.c collection.c extract_timestamps.c filename_treatment.c get_timestamps.c injection_statistics.c peak_finding.c read_lecroy_file.c read_tek_file.c save_timestamps.c stamp_handling.c treat_lecroy_file.c treat_tek_file.c $(COMPILER_OPT)
get_timestamps.o: get_timestamps.c time_ext.h
gcc $(COMPILER_OPT) -c get_timestamps.c -lm
peak_finding.o: peak_finding.c time_ext.h
gcc $(COMPILER_OPT) -c -o peak_finding.o peak_finding.c -lm
calc_time_stamp.o: calc_time_stamp.c time_ext.h
gcc $(COMPILER_OPT) -c -o calc_time_stamp.o calc_time_stamp.c -lm
injection_statistics.o: injection_statistics.c time_ext.h
gcc $(COMPILER_OPT) -c -o injection_statistics.o injection_statistics.c -lm
save_timestamps.o: save_timestamps.c time_ext.h
gcc $(COMPILER_OPT) -c -o save_timestamps.o save_timestamps.c -lm
filename_treatment.o: filename_treatment.c time_ext.h
gcc $(COMPILER_OPT) -c -o filename_treatment.o filename_treatment.c -lm
basic_analysis.o: basic_analysis.c time_ext.h
gcc $(COMPILER_OPT) -c -o basic_analysis.o basic_analysis.c -lm
collection.o: collection.c time_ext.h
gcc $(COMPILER_OPT) -c -o collection.o collection.c -lm
read_lecroy_file.o: read_lecroy_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o read_lecroy_file.o read_lecroy_file.c -lm
read_tek_file.o: read_tek_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o read_tek_file.o read_tek_file.c -lm
stamp_handling.o: stamp_handling.c time_ext.h
gcc $(COMPILER_OPT) -c -o stamp_handling.o stamp_handling.c -lm
treat_lecroy_file.o: treat_lecroy_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o treat_lecroy_file.o treat_lecroy_file.c -lm
treat_tek_file.o: treat_tek_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o treat_tek_file.o treat_tek_file.c -lm
clean:
delete filename_treatment.o basic_analysis.o collection.o read_lecroy_file.o stamp_handling.o treat_lecroy_file.o save_timestamps.o injection_statistics.o calc_time_stamp.o peak_finding.o extract_timestamps read_tek_file.o treat_tek_file.o
ubuntu Makefile:
COMPILER_OPT = -O3
all: extract_timestamps
extract_timestamps: extract_timestamps.c filename_treatment.o basic_analysis.o collection.o \
read_lecroy_file.o read_tek_file.o stamp_handling.o treat_lecroy_file.o \
treat_tek_file.o save_timestamps.o injection_statistics.o calc_time_stamp.o \
peak_finding.o get_timestamps.o time_ext.h
gcc $(COMPILER_OPT) -o extract_timestamps extract_timestamps.c filename_treatment.o \
basic_analysis.o collection.o read_lecroy_file.o read_tek_file.o stamp_handling.o \
treat_lecroy_file.o treat_tek_file.o save_timestamps.o injection_statistics.o \
calc_time_stamp.o peak_finding.o get_timestamps.o; chmod go+rx extract_timestamps -lm
get_timestamps.o: get_timestamps.c time_ext.h
gcc $(COMPILER_OPT) -c get_timestamps.c -lm
peak_finding.o: peak_finding.c time_ext.h
gcc $(COMPILER_OPT) -c -o peak_finding.o peak_finding.c -lm
calc_time_stamp.o: calc_time_stamp.c time_ext.h
gcc $(COMPILER_OPT) -c -o calc_time_stamp.o calc_time_stamp.c -lm
injection_statistics.o: injection_statistics.c time_ext.h
gcc $(COMPILER_OPT) -c -o injection_statistics.o injection_statistics.c -lm
save_timestamps.o: save_timestamps.c time_ext.h
gcc $(COMPILER_OPT) -c -o save_timestamps.o save_timestamps.c -lm
filename_treatment.o: filename_treatment.c time_ext.h
gcc $(COMPILER_OPT) -c -o filename_treatment.o filename_treatment.c -lm
basic_analysis.o: basic_analysis.c time_ext.h
gcc $(COMPILER_OPT) -c -o basic_analysis.o basic_analysis.c -lm
collection.o: collection.c time_ext.h
gcc $(COMPILER_OPT) -c -o collection.o collection.c -lm
read_lecroy_file.o: read_lecroy_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o read_lecroy_file.o read_lecroy_file.c -lm
read_tek_file.o: read_tek_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o read_tek_file.o read_tek_file.c -lm
stamp_handling.o: stamp_handling.c time_ext.h
gcc $(COMPILER_OPT) -c -o stamp_handling.o stamp_handling.c -lm
treat_lecroy_file.o: treat_lecroy_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o treat_lecroy_file.o treat_lecroy_file.c -lm
treat_tek_file.o: treat_tek_file.c time_ext.h
gcc $(COMPILER_OPT) -c -o treat_tek_file.o treat_tek_file.c -lm
clean:
rm filename_treatment.o basic_analysis.o collection.o \
read_lecroy_file.o stamp_handling.o treat_lecroy_file.o save_timestamps.o \
injection_statistics.o calc_time_stamp.o peak_finding.o \
read_tek_file.o treat_tek_file.o \
命令行命令是“mingw32-make.exe”和“make”,不含参数,位于目录中。
我不得不说,我通常不会那样直接编译。
通常我会让一些具有正常工作默认设置的GUI来安慰自己。这可能就是我错过了一些基本的东西的原因。
你能否告诉我为什么windows-executable正在处理数字错误以及为什么我在ubuntu中编译失败?
编辑:
这是主要的C代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include "time_ext.h"
#define DEBUG
//#undef DEBUG
typedef struct{
char Inputfile[64];
char Outputfile[64];
double Fraction;
int Shift;
double Threshold;
int timing;
int TekwithCapHeader; /* 1=tektronix with capital header letter,0=LeCroy */
int TekwithSmallHeader; /* 1=tektronix with small header letter,0=LeCroy */
}gParameters;
gParameters gParms={
"infile.dat",
"outfile.times",
0.5, /* fraction */
8, /* shift */
-8.0, /* threshold in volts */
2, /* timing method; 1=extrapolation to zero, 2=cfd,3=single threshold*/
0, /* type of the scope with a Capital header*/
0 /* type of the scope with a small header*/
};
main(int argc, char **argv){
int subroutine_return_value;
FILE *listfp,*outfp,*logfp;
char lecroyfilename[256],logfilename[256];
char tekfilename[256], tekheaderfilename[256];
/* int events=0,file_nr=0,shot=0,total_events=0; */
void *extr_parameters;
sTraceLimits limits;
int shot_number=0;
int number_of_shots;
int number_of_signals_in_shot, number_of_signals_total;
// int treat_lecroy_files(char *, FILE *, void *, FILE *,int, int *); /* might change */
uExtractedParameter get_extraction_parameter(void *, int, int);
void *parameter_collection(gParameters);
/* start code */
/* initialize some things */
if(getArgs(argc,argv)!=0){
printf(" !! invalid arguments.....\n ...... bye!\n");exit(-3);}
sprintf(logfilename,"%s.log",gParms.Outputfile);
if((listfp=fopen(gParms.Inputfile,"r"))==NULL){
fprintf(stderr," !! ERROR: can't open main-inputfile %s, terminating...\n",gParms.Inputfile);exit(-1);}
if((outfp=fopen(gParms.Outputfile,"w"))==NULL){
fprintf(stderr," !! ERROR: can't open outputfile %s, terminating...\n",gParms.Outputfile);exit(-1);}
if((logfp=fopen(logfilename,"w"))==NULL){
fprintf(stderr," !! ERROR: can't open logfile %s, terminating...\n",logfilename);exit(-1);}
fprintf(logfp,"logfile to outputfile %s created from inputfile %s\n"
"user-changeable settings:\n"
"shift = %d bins\tfraction = %le\tthreshold=%le V\n"\
"timing method=%2d\n"
"report on single files to follow\n\n",
gParms.Outputfile,gParms.Inputfile,
gParms.Shift,gParms.Fraction,gParms.Threshold,gParms.timing);
extr_parameters=parameter_collection(gParms);
limits.limits_active=LIMITS_INACTIVE;
/*** if switch -X or -x ****/
if((gParms.TekwithCapHeader ==1)||(gParms.TekwithSmallHeader ==1))
{
/* treat the Tektronix file */
while(!feof(listfp)){
fgets(tekfilename,256,listfp);
if(feof(listfp)) continue;
if(tekfilename[strlen(tekfilename)-1]=='\n')
tekfilename[strlen(tekfilename)-1]='\0';
#ifdef DEBUG
printf(" *starting treating file %s\n",tekfilename);
#endif
subroutine_return_value=treat_tek_file(tekfilename, tekheaderfilename,
outfp,extr_parameters,logfp,limits,
shot_number, &number_of_signals_in_shot, &number_of_shots);
/* does everything, or should do so at least ;-) */
/* but now handle the return_value !!! */
/* next sum the statistics, once it is returned by treat_lecroy_file */
if(number_of_signals_in_shot>0){
shot_number += number_of_shots;
number_of_signals_total+=number_of_signals_in_shot;
}
}
}
else
{
/* treat LeCroy file */
while(!feof(listfp)){
fgets(lecroyfilename,256,listfp);
if(feof(listfp)) continue;
if(lecroyfilename[strlen(lecroyfilename)-1]=='\n')
lecroyfilename[strlen(lecroyfilename)-1]='\0';
#ifdef DEBUG
printf(" *start treating file %s\n",lecroyfilename);
#endif
subroutine_return_value=treat_lecroy_file(lecroyfilename,outfp,extr_parameters,logfp,limits,
shot_number, &number_of_signals_in_shot);
/* does everything, or should do so at least ;-) */
/* but now handle the return_value !!! */
/* next sum the statistics, once it is returned by treat_lecroy_file */
if(number_of_signals_in_shot>0){
shot_number++;
number_of_signals_total+=number_of_signals_in_shot;
}
}
}
fclose(outfp);
fclose(logfp);
printf("\n");
}
/* **********************************8 subroutines ****************************************8 */
int getArgs(int argc,char **argv)
{ char opt;
int back=0;
int usage(char *);
if(argc==1) usage(argv[0]);
// while ((opt = (char)getopt(argc,argv,"hi:o:f:g:b:p:c:t:u:s:xX")) !=EOF)
while ((opt = (char)getopt(argc,argv,"hi:o:t:f:b:e:xX")) !=EOF)
{
switch(opt)
{
case 'h': usage(argv[0]); break;
case 'i': strcpy(gParms.Inputfile,optarg); break;
case 'o': strcpy(gParms.Outputfile,optarg); break;
case 't': gParms.Threshold=-fabs((double)atof(optarg)); break;
case 'f': gParms.Fraction=(double)atof(optarg); break;
case 'b': gParms.Shift=atoi(optarg); break;
case 'e': gParms.timing=atoi(optarg); break;
case 'x': gParms.TekwithSmallHeader=1; break;
case 'X': gParms.TekwithCapHeader=1; break;
/* case 'f': gParms.Minimum_efficiency=(double)atof(optarg); break; */
case '?': back=-1; break; /* to return error */
}
}
return(back);
}
int usage(char *programm)
{ fprintf(stderr,
"\n usage: %s \n\n"
" -h usage\n"
" -i [filename] inputfile Def: infile.dat\n"
" -o [filename] outputfile Def: outfile.times\n"
" -t [double] Threshold Def: -8. V \n"
" -f [double] Fraction Def: 0.5 \n"
" -b [int] Shift in bin Def: 4 \n"
" -e [int] Timestamps extraction Def: 1 \n"
" -x,X for Tektronix format \n\n"
" inputfile is one file containing a list of LeCroy or Tektornix Datafiles\n"
" outputfile contains timestamps in ns, shots separated by blank line\n"
" in addition a log-file (outputfile.log) is created\n"
" options t is the threshold, in fact threshold*sigma(of noise) is the threshold\n"
" For tektronix data (high sampling rate >= 20Gs/s): \n"
" -t: threshod, actual threshold is: threshold*sigma \n"
" -e: timing method. 1=extraploation to zero (by linear fit), 2=cfd (by linear fit).\n"
" -X, -x respectively correspond to *.WFD and *.wfd(header file),however, in my case \n"
" this does not matter, and the present version can deal with the header automatically \n"
" For LeCroy data (low sampling rate < 20 Gs/s): \n"
" -t: threshod, actual threshold is: threshold*sigma \n"
" -f: fraction, \n"
" -b: shift in bin, \n"
" time stamp discriminator: normal cfd, \n"
" Last modified 2008.10 Baohua Sun \n\n",
programm);
exit(-1);
}
Makefile见上文
输出Linux:
gcc -Wall -g -o extract_timestamps extract_timestamps.c filename_treatment.o \
basic_analysis.o collection.o read_lecroy_file.o read_tek_file.o stamp_handling.o \
treat_lecroy_file.o treat_tek_file.o save_timestamps.o injection_statistics.o \
calc_time_stamp.o peak_finding.o get_timestamps.o; chmod go+rx extract_timestamps -lm
extract_timestamps.c:37:1: Warnung: Rückgabetyp ist auf »int« voreingestellt [-Wreturn-type]
extract_timestamps.c: In Funktion »main«:
extract_timestamps.c:59:3: Warnung: Implizite Deklaration der Funktion »getArgs« [-Wimplicit-function-declaration]
extract_timestamps.c:93:7: Warnung: Implizite Deklaration der Funktion »treat_tek_file« [-Wimplicit-function-declaration]
extract_timestamps.c:122:5: Warnung: Implizite Deklaration der Funktion »treat_lecroy_file« [-Wimplicit-function-declaration]
extract_timestamps.c:38:7: Warnung: Variable »subroutine_return_value« gesetzt, aber nicht verwendet [-Wunused-but-set-variable]
extract_timestamps.c:140:1: Warnung: Kontrollfluss erreicht Ende von Nicht-void-Funktion [-Wreturn-type]
basic_analysis.o: In function `get_baseline':
basic_analysis.c:(.text+0x7b): undefined reference to `pow'
basic_analysis.c:(.text+0x216): undefined reference to `sqrt'
basic_analysis.c:(.text+0x241): undefined reference to `pow'
basic_analysis.c:(.text+0x263): undefined reference to `sqrt'
basic_analysis.o: In function `get_tek_baseline':
basic_analysis.c:(.text+0x2fb): undefined reference to `pow'
basic_analysis.c:(.text+0x496): undefined reference to `sqrt'
basic_analysis.c:(.text+0x4c1): undefined reference to `pow'
basic_analysis.c:(.text+0x4e3): undefined reference to `sqrt'
read_tek_file.o: In function `read_tek_data':
read_tek_file.c:(.text+0x362): undefined reference to `pow'
calc_time_stamp.o: In function `fitline':
calc_time_stamp.c:(.text+0x165): undefined reference to `sqrt'
calc_time_stamp.o: In function `timestamp_line':
calc_time_stamp.c:(.text+0x323): undefined reference to `sqrt'
calc_time_stamp.c:(.text+0x349): undefined reference to `sqrt'
calc_time_stamp.o: In function `timestamp_parabola1':
calc_time_stamp.c:(.text+0xc28): undefined reference to `sqrt'
calc_time_stamp.o: In function `timestamp_parabola2':
calc_time_stamp.c:(.text+0x1063): undefined reference to `pow'
calc_time_stamp.c:(.text+0x107f): undefined reference to `pow'
calc_time_stamp.c:(.text+0x10f2): undefined reference to `pow'
calc_time_stamp.c:(.text+0x116f): undefined reference to `pow'
calc_time_stamp.c:(.text+0x12a8): undefined reference to `sqrt'
calc_time_stamp.c:(.text+0x12e9): undefined reference to `sqrt'
calc_time_stamp.c:(.text+0x1333): undefined reference to `sqrt'
calc_time_stamp.c:(.text+0x1364): undefined reference to `sqrt'
calc_time_stamp.c:(.text+0x13c5): undefined reference to `sqrt'
calc_time_stamp.o:calc_time_stamp.c:(.text+0x144e): more undefined references to `sqrt' follow
collect2: ld gab 1 als Ende-Status zurück
chmod: Ungültige Option -- l
„chmod --help“ gibt weitere Informationen.
make: *** [extract_timestamps] Fehler 1
输出Windows:
gcc -lm -o extract_timestamps.exe basic_analysis.c calc_time_stamp.c collection.c extract_timestamps.c filename_treatment.c get_timestamps.c injection_statistics.c peak_finding.c read_lecroy_file.c read_tek_file.c save_timestamps.c stamp_handling.c treat_lecroy_file.c treat_tek_file.c -O3
filename_treatment.c: In Funktion »separate_filename«:
filename_treatment.c:23:26: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strrchr« [standardmäßig aktiviert]
filename_treatment.c:25:7: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« [standardmäßig aktiviert]
filename_treatment.c:28:11: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strlen« [standardmäßig aktiviert]
filename_treatment.c:32:5: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strncpy« [standardmäßig aktiviert]
filename_treatment.c:36:11: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strlen« [standardmäßig aktiviert]
filename_treatment.c:40:5: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strncpy« [standardmäßig aktiviert]
filename_treatment.c: In Funktion »make_tek_header_filename«:
filename_treatment.c:73:13: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strlen« [standardmäßig aktiviert]
filename_treatment.c:75:3: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« [standardmäßig aktiviert]
filename_treatment.c:77:20: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strrchr« [standardmäßig aktiviert]
filename_treatment.c:80:7: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
filename_treatment.c:90:6: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
filename_treatment.c:100:8: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
filename_treatment.c:104:8: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
read_lecroy_file.c: In Funktion »read_lecroy_header«:
read_lecroy_file.c:55:6: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strlen« [standardmäßig aktiviert]
read_lecroy_file.c:59:3: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« [standardmäßig aktiviert]
read_lecroy_file.c:69:3: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
read_lecroy_file.c:134:8: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strncpy« [standardmäßig aktiviert]
read_lecroy_file.c: In Funktion »read_lecroy_data«:
read_lecroy_file.c:153:3: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« [standardmäßig aktiviert]
read_lecroy_file.c:154:3: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
read_tek_file.c: In Funktion »read_tek_header«:
read_tek_file.c:67:7: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« [standardmäßig aktiviert]
read_tek_file.c:70:11: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
read_tek_file.c:73:7: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcat« [standardmäßig aktiviert]
编辑: 执行windows / linux可执行文件的问题是我使用windows将文件列表作为输入文件。该程序有一个简单的文件名列表可供搜索。但是,C不喜欢\ r \ n,但只有\ n,因此它随机出现在数字和文件名上的尾随\ r \ n。 Windows makefile正在运行,linux-makefile已经过时,文件顺序错误等。
答案 0 :(得分:2)
您的Linux Makefile
错误(它将-lm
传递给chmod
命令,但-lm
应作为链接gcc
命令的最后一个参数传递)。请记住,gcc
的程序参数顺序非常重要。
你真的不需要chmod
命令,如果你这样做,它应该在Makefile
<的单独的行上/ p>
您应该运行make -p
一次,以了解make
已知的内置规则。
尝试类似
的内容 CC= gcc
CFLAGS= -g -Wall
LDLIBS= -lm
SOURCES= extract_timestamps.c filename_treatment.c basic_analysis.c \
collection.c read_lecroy_file.c read_tek_file.c \
stamp_handling.c treat_lecroy_file.c treat_tek_file.c \
save_timestamps.c injection_statistics.c calc_time_stamp.c \
peak_finding.c get_timestamps.c
OBJECTS= $(patsubst %.c, %.o, $(SOURCES))
.PHONY: all clean
all: extract_timestamps
extract_timestamps: $(OBJECTS)
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
## add or autogenerate rules for object files.
在适当的时候用一个 tab 字符替换上面的多个空格。
上述Makefile
仍然不完整。您需要完成它(并且您需要一个clean
目标)。见this example。您可能需要:
%.o: %.c time_ext.h
顺便说一句,我不建议在您的案例中使用Makefile
生成器,例如cmake
。您的程序非常简单,可以通过普通Makefile
通过GUI编译是一个坏习惯(您可以在M-x compile
中尝试emacs
):GUI工具正在运行命令来构建您的程序,它正在隐藏它们。所以当出现问题时你会变得无助。熟悉Linux命令,它们非常有用!
Windows和Linux可执行文件之间的不同行为(对于相同的源代码)可能有很多原因:undefined behavior,实现floating point的不同方式 - 实现不仅依赖于处理器,但依赖于操作系统,不同的x86 calling conventions,不同的编译器版本。编写portable代码是一项困难的艺术。
改进您的代码,直到您没有收到任何警告且编译器没有错误(例如gcc -Wall
)