Reputation: 33
When using Makefile, I get error undefined reference
when linking objs into executable.
But I am sure that I have add include path and library link in options of g++.
To do so, I copy and paste C_FLAGS
to all Makefiles, and path to 3rdparty library is absolute path.
If my 3rdparty path is wrong, then make will tell me that cannot find -lfftw3
when compiling obj.
It didn't. So I am sure that my 3rdparty path is right.
But why I still get undefined reference
? Thank you for your reply!
My error log:
g++ -g -O3 -lm -I/public/home/AAAAA/BBBBB/IBM/../../fftw3/include -L/public/home/AAAAA/BBBBB/IBM/../../fftw3/lib -lfftw3 -fopenmp -std=c++1z -o /public/home/AAAAA/BBBBB/IBM/build/bin/IBM build/obj/*.o
build/obj/main.o: In function `NeumannPESolver2D::NeumannPESolver2D(unsigned int, unsigned int)':
/public/home/AAAAA/BBBBB/IBM/src/pe_solver/neumann_pe_solver_2d.h:48: undefined reference to `fftw_plan_dft_r2c_1d'
build/obj/neumann_pe_solver_2d.o: In function `NeumannPESolver2D::solve(No_bound_field&, Neumann_field&) [clone ._omp_fn.0]':
neumann_pe_solver_2d.cpp:(.text+0x6c8): undefined reference to `fftw_execute_dft_r2c'
build/obj/neumann_pe_solver_2d.o: In function `NeumannPESolver2D::solve(No_bound_field&, Neumann_field&) [clone ._omp_fn.2]':
neumann_pe_solver_2d.cpp:(.text+0xe90): undefined reference to `fftw_execute_dft_r2c'
neumann_pe_solver_2d.cpp:(.text+0xf10): undefined reference to `fftw_execute_dft_r2c'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
My layered Makefile structure is as below. There are only two kinds of Makefile. One is placed in subfolder, and it is recursive. The other is placed in top root folder, it controls which subfolder to make.
└─AAAAA
└─BBBBB
├─fftw3
└─IBM
│ Makefile
│
└─src
│ CMakeLists.txt
│ main.cpp
│ Makefile
│ ...
│
├─helper
│ airfoil_reader.hpp
│ Makefile
│
├─ns_solver
│ ib_cylinder.hpp
│ ...
│ Makefile
│
├─pe_solver
│ Makefile
│ neumann_pe_solver_2d.cpp
│ neumann_pe_solver_2d.h
│
└─structs
field.hpp
Makefile
var.hpp
My recursive Makefile:
INCLUDE_DIR = -I../
FFTW_DIR = $(ROOT_DIR)/../../fftw3
C_FLAGS = -g -O3 -lm -I${FFTW_DIR}/include -L${FFTW_DIR}/lib -lfftw3 -fopenmp -std=c++1z
SUBDIRS = $(shell ls -l | grep ^d | awk '{print $$9}')
CUR_SOURCE = ${wildcard *.cpp}
CUR_OBJS = ${patsubst %.cpp, %.o, $(CUR_SOURCE)}
all:$(SUBDIRS) $(CUR_OBJS)
$(SUBDIRS):ECHO
make -C $@
$(CUR_OBJS):%.o:%.cpp
$(CC) $(INCLUDE_DIR) $(C_FLAGS) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
ECHO:
@echo $(SUBDIRS)
My top root Makefile:
CC = g++
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}')
ROOT_DIR=$(shell pwd)
BIN=IBM
OBJS_DIR=build/obj
BIN_DIR=build/bin
export CC BIN OBJS_DIR BIN_DIR ROOT_DIR
FFTW_DIR = $(ROOT_DIR)/../../fftw3
C_FLAGS = -g -O3 -lm -I${FFTW_DIR}/include -L${FFTW_DIR}/lib -lfftw3 -fopenmp -std=c++1z
all:
make -C $(SUBDIRS)
$(CC) $(C_FLAGS) -o $(ROOT_DIR)/$(BIN_DIR)/$(BIN) $(OBJS_DIR)/*.o
.PHONY: clean cleanall
clean:
rm -rf ${BIN_DIR}
cleanall:
rm -rf build
mkdir build
mkdir ${OBJS_DIR}
mkdir ${BIN_DIR}
I have try copy and paste C_FLAGS
to all Makefiles, and path to 3rdparty library is absolute path.
Because all g++ compiling have same options, so it should be always correct, but it didn't.
What I expect is objs pass compiling.
By the way, I have written single file version, and it can compile successfully:
FFTW_DIR = ../../fftw3
IBM: ./c_oop_ib_demo.cpp
g++ $^ -g -O3 -lm -I${FFTW_DIR}/include -L${FFTW_DIR}/lib -lfftw3 -fopenmp -std=c++11 -o $@
Upvotes: 0
Views: 25