undefined reference to 'xxx' 에 대해 질문드립니다. ㅎ
안녕하세요 저는 프로그래밍을 배우고 있는 학생입니다.
제가 어떤 프로그램의 makefile을 수정해서 프로그램을 돌릴 일이 있어서 makefile을 수정해보았습니다.
그런데 link하는 부분에서
mpif77 main.o run.o predict.o begrun.o endrun.o global.o timestep_cool.o init.o restart.o io.o accel.o read_ic.o ngb.o system.o allocate.o density.o gravtree.o hydra_cool.o driftfac.o domain.o allvars.o potential.o forcetree.o peano.o gravtree_forcetest.o pm_periodic.o pm_nonperiodic.o longrange.o external_force.o nrutil.o cooling.o get_lambda.o -g -L/mpich2-install/lib -L/home/kwchun/gsl/lib -lgsl -lgslcblas -lm -L/home/kwchun/fftw/lib -lsrfftw_mpi -lsfftw_mpi -lsrfftw -lsfftw -o Gadget2
cooling.o: In function `DoCooling':
cooling.c:(.text+0x95): undefined reference to `get_lambda_'
collect2: ld returned 1 exit status
이와 같은 에러가 생기네요.
QnA에 나와있는 글을 보고 해결해보려 했는데 잘 안되서 질문 드립니다.
일단 마지막에 getlambda.o는 getlambda.f로 만들어지는 object 파일입니다.
나머지 .o 파일들은 .c 파일에서 만들어진 것입니다.
cooling.c에서 Docooling이라는 함수에서 getlambda.f(서브루틴만 존재합니다.)의 getlambda라는 서브루틴을 불러오는 부분이 있습니다.
Doccoling 함수에서 getlambda라는 서브루틴을 불러오지 않으면 저런 에러가 뜨지 않는데 불러오게끔 만들어두면 에러가 생겨서 다음 일을 진행하지 못하고 있습니다.
이게 어디서 생긴 문제인지 알 수 있을까요?
제 생각에는 fortran과 c 두 언어를 같이 사용하는데서 문제가 생긴 것이 아닐까 하는데 인터넷에서 두 언어를 같이 사용해서 makefile을 만드는 법을 찾을 수 없어
이렇게 글을 남깁니다.
도움 부탁드립니다.
마지막으로 makefile 내용도 같이 올립니다. ㅎ
#---------------------------------------------------------------------- # From the list below, please activate/deactivate the options that # apply to your run. If you modify any of these options, make sure # that you recompile the whole code by typing "make clean; make". # # Look at end of file for a brief guide to the compile-time options. #---------------------------------------------------------------------- #--------------------------------------- Basic operation mode of code #OPT += -DPERIODIC OPT += -DUNEQUALSOFTENINGS #--------------------------------------- Things that are always recommended OPT += -DPEANOHILBERT OPT += -DWALLCLOCK #--------------------------------------- TreePM Options #OPT += -DPMGRID=128 #OPT += -DPLACEHIGHRESREGION=3 #OPT += -DENLARGEREGION=1.2 #OPT += -DASMTH=1.25 #OPT += -DRCUT=4.5 #--------------------------------------- Single/Double Precision #OPT += -DDOUBLEPRECISION #OPT += -DDOUBLEPRECISION_FFTW #--------------------------------------- Time integration options OPT += -DSYNCHRONIZATION #OPT += -DFLEXSTEPS #OPT += -DPSEUDOSYMMETRIC #OPT += -DNOSTOP_WHEN_BELOW_MINTIMESTEP #OPT += -DNOPMSTEPADJUSTMENT #--------------------------------------- Output #OPT += -DHAVE_HDF5 #OPT += -DOUTPUTPOTENTIAL #OPT += -DOUTPUTACCELERATION #OPT += -DOUTPUTCHANGEOFENTROPY #OPT += -DOUTPUTTIMESTEP #--------------------------------------- Things for special behaviour #OPT += -DNOGRAVITY #OPT += -DNOTREERND #OPT += -DNOTYPEPREFIX_FFTW #OPT += -DLONG_X=60 #OPT += -DLONG_Y=5 #OPT += -DLONG_Z=0.2 #OPT += -DTWODIMS #OPT += -DSPH_BND_PARTICLES #OPT += -DNOVISCOSITYLIMITER #OPT += -DCOMPUTE_POTENTIAL_ENERGY #OPT += -DLONGIDS #OPT += -DISOTHERM_EQS #OPT += -DADAPTIVE_GRAVSOFT_FORGAS #OPT += -DSELECTIVE_NO_GRAVITY=2+4+8+16 #--------------------------------------- Testing and Debugging options #OPT += -DFORCETEST=0.1 #--------------------------------------- Glass making #OPT += -DMAKEGLASS=262144 #---------------------------------------------------------------------- # Here, select compile environment for the target machine. This may need # adjustment, depending on your local system. Follow the examples to add # additional target platforms, and to get things properly compiled. #---------------------------------------------------------------------- #--------------------------------------- Select some defaults CC = mpicc # sets the C-compiler FC = mpif77 OPTIMIZE = -O2 -Wall -g # sets optimization and warning flags MPICHLIB = -lmpich #--------------------------------------- Select target computer SYSTYPE="MPA" #SYSTYPE="Mako" #SYSTYPE="Regatta" #SYSTYPE="RZG_LinuxCluster" #SYSTYPE="RZG_LinuxCluster-gcc" #SYSTYPE="OpteronMPA" #SYSTYPE="OPA-Cluster32" #SYSTYPE="OPA-Cluster64" #--------------------------------------- Adjust settings for target computer ifeq ($(SYSTYPE),"MPA") CC = mpicc FC = mpif77 OPTIMIZE = -O3 -Wall GSL_INCL = -I/home/kwchun/gsl/include GSL_LIBS = -L/home/kwchun/gsl/lib #"-R /home/kwchun/gsl/lib"# -Wl,"-R /home/myjeon/gadget2/usr/lib" FFTW_LIBS = -L/home/kwchun/fftw/lib FFTW_INCL = -I/home/kwchun/fftw/include MPICHLIB = -L/mpich2-install/lib HDF5INCL = -I/home/kwchun/hdf5/include HDF5LIB = -L/home/kwchun/hdf5/lib endif OPTIONS = $(OPTIMIZE) $(OPT) EXEC = Gadget2 OBJS = main.o run.o predict.o begrun.o endrun.o global.o \ timestep_cool.o init.o restart.o io.o \ accel.o read_ic.o ngb.o \ system.o allocate.o density.o \ gravtree.o hydra_cool.o driftfac.o \ domain.o allvars.o potential.o \ forcetree.o peano.o gravtree_forcetest.o \ pm_periodic.o pm_nonperiodic.o longrange.o \ external_force.o nrutil.o cooling.o get_lambda.o INCL = allvars.h proto.h tags.h external_force.h nrutil.h mpif.h header.h cooling.h Makefile CFLAGS = $(OPTIONS) $(GSL_INCL) $(FFTW_INCL) $(HDF5INCL) FCFLAGS = $(OPTIONS) $(GSL_INCL) $(FFTW_INCL) $(HDF5INCL) ifeq (NOTYPEPREFIX_FFTW,$(findstring NOTYPEPREFIX_FFTW,$(OPT))) # fftw installed with type prefix? FFTW_LIB = $(FFTW_LIBS) -lrfftw_mpi -lfftw_mpi -lrfftw -lfftw else ifeq (DOUBLEPRECISION_FFTW,$(findstring DOUBLEPRECISION_FFTW,$(OPT))) FFTW_LIB = $(FFTW_LIBS) -ldrfftw_mpi -ldfftw_mpi -ldrfftw -ldfftw else FFTW_LIB = $(FFTW_LIBS) -lsrfftw_mpi -lsfftw_mpi -lsrfftw -lsfftw endif endif LIBS = $(HDF5LIB) -g $(MPICHLIB) $(GSL_LIBS) -lgsl -lgslcblas -lm $(FFTW_LIB) $(EXEC): $(OBJS) $(FC) $(OBJS) $(LIBS) -o $(EXEC) $(OBJS): $(INCL) clean: rm -f $(OBJS) $(EXEC)
undefined reference to
undefined reference to `get_lambda_'
이것은 링커 에러입니다.
링크라는 단어를 사용하신걸로 봐선 링크가 뭔지는 알고 계신거 같은데...
노파심에 말씀드리자면, 링크란 서로 독립적으로 컴파일된 목적파일들에 포함된 심볼들을 연결해주는 단계입니다.
컴파일 단계에서는 extern이나 전방선언등으로 선언된 소스파일의 바깥에 있는 심볼들(함수명, 변수명등)을 몰라도 컴파일은 되지만, 프로그램이 실행되려면 이 심볼이 실제로 어디에 연결되는지를 알아야 하며, 이 역할을 수행하는게 링커입니다.
지금 링커는 get_lambda_가 정의되어 있지 않다고 말하고 있습니다.
즉, 선언만 되어있고 정의(실제 함수 내용)가 어딨는지 도통 찾을수가 없네 이겁니다.
말씀하신대로 get_lambda_가 getlambda.o안에 들어있다면 링크단계에 getlambda.o도 같이 링크해주어야 합니다.
그래야 정의를 찾아서 링크가 가능합니다.
만약 외부라이브러리에 그 링크가 들어있다면 그 라이브러리를 -l옵션등으로 포함시켜줘야합니다.
답변 감사합니다. ㅎ
말씀해주신대로 get_lambda.o도 같이 링크되었는데도 에러가 났습니다.
그런데 답글을 읽다가 getlambda를 읽으면서 제가 subroutine의 이름과 fortran 파일 이름을 똑같이 한게 문제가 아닐까 싶어
soubroutine 이름을 getlambda로 바꿔보니 문제 없이 링크되서 실행파일이 나왔습니다. ㅎㅎ
답변 감사합니다~ ㅎ
댓글 달기