CheapMeow
CheapMeow

Reputation: 33

Linux Makefile undefined reference only when linking objs into executable

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

Answers (0)

Related Questions