Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined references while compiling project #820

Closed
ZhengLinLei opened this issue Apr 18, 2024 · 17 comments
Closed

Undefined references while compiling project #820

ZhengLinLei opened this issue Apr 18, 2024 · 17 comments

Comments

@ZhengLinLei
Copy link

ZhengLinLei commented Apr 18, 2024

I'm having troubles compiling my project. It shows undefined references error.

Information:

  • I have everything installed correctly. (libpq-devel, postgresql-devel)
  • I have installed libpqxx (v7.9.0) manually with:
./configure --with-postgres-lib=/usr/pgsql-14/lib --with-postgres-include=/usr/pgsql-14/include
make && make install

Problem

When I try to compile the project with:

g++ -Ih -I/usr/pgsql-14/include/ -I/usr/local/include/ -L/usr/pgsql-14/lib/ -lpthread -lpqxx -lpq ../build/base_DB.o ../build/base_ServerComm.o ../build/main_RouteServer.o -o ../dist/server

I have this error:

#0 2.411 g++ -Ih -I/usr/pgsql-14/include/ -I/usr/local/include/ -L/usr/pgsql-14/lib/ -lpthread -lpqxx -lpq ../build/base_DB.o ../build/base_ServerComm.o ../build/main_RouteServer.o -o ../dist/OronetaCoreServer
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
#0 2.477 base_DB.cpp:(.text+0x198): undefined reference to `pqxx::argument_error::argument_error(std::string const&)'
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `DB_connection(char const*, int, char const*, char const*)':
#0 2.477 base_DB.cpp:(.text+0x270): undefined reference to `pqxx::connection::operator=(pqxx::connection&&)'
#0 2.477 /usr/bin/ld: base_DB.cpp:(.text+0x280): undefined reference to `pqxx::connection::is_open() const'
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `__static_initialization_and_destruction_0(int, int)':
#0 2.477 base_DB.cpp:(.text+0x4cc): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
#0 2.477 /usr/bin/ld: base_DB.cpp:(.text+0x50c): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
#0 2.477 /usr/bin/ld: base_DB.cpp:(.text+0x54c): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
#0 2.477 /usr/bin/ld: base_DB.cpp:(.text+0x58c): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `pqxx::check_version()':
#0 2.477 base_DB.cpp:(.text._ZN4pqxx13check_versionEv[_ZN4pqxx13check_versionEv]+0x4c): undefined reference to `pqxx::internal::check_pqxx_version_7_9()'
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `pqxx::connection::connection(char const*)':
#0 2.477 base_DB.cpp:(.text._ZN4pqxx10connectionC2EPKc[_ZN4pqxx10connectionC5EPKc]+0x50): undefined reference to `pqxx::connection::init(char const*)'
#0 2.477 /usr/bin/ld: ../build/base_DB.o: in function `pqxx::connection::~connection()':
#0 2.477 base_DB.cpp:(.text._ZN4pqxx10connectionD2Ev[_ZN4pqxx10connectionD5Ev]+0x10): undefined reference to `pqxx::connection::close()'
#0 2.478 /usr/bin/ld: ../build/main_RouteServer.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
#0 2.478 main_RouteServer.cpp:(.text+0x198): undefined reference to `pqxx::argument_error::argument_error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
#0 2.478 /usr/bin/ld: ../build/main_RouteServer.o: in function `__static_initialization_and_destruction_0(int, int)':
#0 2.478 main_RouteServer.cpp:(.text+0x12fc): undefined reference to `pqxx::internal::demangle_type_name[abi:cxx11](char const*)'
#0 2.478 /usr/bin/ld: main_RouteServer.cpp:(.text+0x133c): undefined reference to `pqxx::internal::demangle_type_name[abi:cxx11](char const*)'
#0 2.478 /usr/bin/ld: main_RouteServer.cpp:(.text+0x14bc): undefined reference to `pqxx::internal::demangle_type_name[abi:cxx11](char const*)'
#0 2.478 /usr/bin/ld: main_RouteServer.cpp:(.text+0x1630): undefined reference to `pqxx::internal::demangle_type_name[abi:cxx11](char const*)'
#0 2.486 collect2: error: ld returned 1 exit status
@ZhengLinLei ZhengLinLei changed the title Undefined references compiling project Undefined references while compiling project Apr 18, 2024
@tt4g
Copy link
Contributor

tt4g commented Apr 18, 2024

Similar issue #732

This may be due to different compile-time options, especially the -std=<CXX_VERSION> flag.
Do you know what the options are when you run the make command?

@ZhengLinLei
Copy link
Author

It use by default C++17 for the compilation. Also I tried changing it to C++20 but doesn't work.

@tt4g
Copy link
Contributor

tt4g commented Apr 18, 2024

If the compile options match, then there may be another version libpqxx installed on the machine and the linker links to it.

@ZhengLinLei
Copy link
Author

ZhengLinLei commented Apr 18, 2024

Nope. I'm using a docker container with empty RHEL9 image, and this is all the portion of dockerfile code relationated with libpqxx:

# Install postgresql library libpqxx
RUN yum install --nogpgcheck -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm && \
    yum install --nogpgcheck --skip-broken -y postgresql14-14.7 postgresql14-devel-14.7 postgresql14-libs-14.7

WORKDIR /opt

# Download libpqxx
RUN wget https://github.com/jtv/libpqxx/archive/refs/tags/7.9.0.tar.gz -O Libpqxx.tar.gz
# Create directory for pqxx
RUN mkdir -p libpqxx
# Extract libpqxx
RUN tar xvfz Libpqxx.tar.gz -C libpqxx --strip-components=1

WORKDIR /opt/libpqxx
RUN ./configure --with-postgres-lib=/usr/pgsql-14/lib --with-postgres-include=/usr/pgsql-14/include --build=aarch64-unknown-linux-gnu
RUN make && make install

@tt4g
Copy link
Contributor

tt4g commented Apr 18, 2024

Is the default compiler for that Docker image g++? If not, libpqxx may be built with a different compiler unless you specify the compiler by CXX environment variable.

@ZhengLinLei
Copy link
Author

Yes, the default compiler is g++. By the way I tried compiling with prebuilt libpqxx with yum, and I got fewer errors.

6.625 g++ -std=c++17 -Ih -I/usr/pgsql-14/include/ -I/usr/include/ -L/usr/pgsql-14/lib/ -L/usr/lib64/ -lpthread -lpqxx -lpq ../build/base_DB.o ../build/base_ServerComm.o ../build/main_RouteServer.o -o ../dist/OronetaCoreServer
6.821 /usr/bin/ld: ../build/base_DB.o: in function `pqxx::internal::(anonymous namespace)::throw_for_encoding_error(char const*, char const*, unsigned long, unsigned long)':
6.822 base_DB.cpp:(.text+0x1ab): undefined reference to `pqxx::argument_error::argument_error(std::string const&)'
6.822 /usr/bin/ld: ../build/base_DB.o: in function `__static_initialization_and_destruction_0(int, int)':
6.822 base_DB.cpp:(.text+0x4d1): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
6.822 /usr/bin/ld: base_DB.cpp:(.text+0x4ff): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
6.822 /usr/bin/ld: base_DB.cpp:(.text+0x52d): undefined reference to `pqxx::internal::demangle_type_name(char const*)'
6.822 /usr/bin/ld: base_DB.cpp:(.text+0x55b): undefined reference to `pqxx::internal::demangle_type_name(char const*)'

@tt4g
Copy link
Contributor

tt4g commented Apr 19, 2024

Are object files ( base_DB.o, base_ServerComm.o ...) built with the same image?
And what happens by adding RUN dnf group install -y "Development Tools" to the Dockerfile?

@ZhengLinLei
Copy link
Author

Are object files ( base_DB.o, base_ServerComm.o ...) built with the same image?

Yes.

And what happens by adding RUN dnf group install -y "Development Tools" to the Dockerfile?

Cannot find it because I don't have any official package suscription. I'm installing all the packages individually

RUN yum update -y
RUN yum install -y  \
        wget        \ 
        tar         \
        vim         \
        gcc-c++     \
        make        \
        cmake       \
        openssl-devel
        

@tt4g
Copy link
Contributor

tt4g commented Apr 19, 2024

If you have built base_DB.o and others with the same compile options as libpqxx, there should be no logical reason for a link error due to undefined reference.
The missing symbols must either be due to different mangle rules or different compilation options, but I can't think of a better cause.

@ZhengLinLei
Copy link
Author

A will try to find any other solution to fix this using other OS image or using libpq++. Thanks for helping me. 😄

@jtv
Copy link
Owner

jtv commented Apr 19, 2024

@ZhengLinLei to set an explicit C++ version, add this option to the configure command line: CXXFLAGS=-std=c++17 (for C++17), or CXXFLAGS=-std=c++20 (for C++20), etc.

@jtv
Copy link
Owner

jtv commented Apr 19, 2024

@ZhengLinLei it looks like a very strange problem... I see some of the errors that you'd normally get when libpqxx and your application are compiled differently, or you're getting a different libpqxx version at link time than at compile time. But I also see much more basic link errors.

Could the libpqxx binary you built be damaged somehow, or even missing from the install location?

AFAIK it shouldn't matter but... What if you put the -lpqxx -lpq -lpthread on the command line after your own object files?

@ZhengLinLei
Copy link
Author

@ZhengLinLei it looks like a very strange problem... I see some of the errors that you'd normally get when libpqxx and your application are compiled differently, or you're getting a different libpqxx version at link time than at compile time. But I also see much more basic link errors.

Using the avaliable package with yum (libpqxx v7.9.0) , the lib is installed in /usr/lib64 and the headers in /usr/include

g++ -std=c++17 -Ih -I/usr/pgsql-14/include/ -I/usr/include/ -L/usr/pgsql-14/lib/ -L/usr/lib64/ -lpthread -lpqxx -lpq ../build/base_DB.o ../build/base_ServerComm.o ../build/main_RouteServer.o -o ../dist/OronetaCoreServer

Lib
imagen

Include
imagen
imagen

Could the libpqxx binary you built be damaged somehow, or even missing from the install location?

As you see, I tried using the prebuilt package and same errors.

It is very strange, I tried everything from internet and similar issues solutions, and nothing worked.

Additional information

Makefile

# Makefile  C

# Directories
SRC_DIR = c
INC_DIR = -Ih -I/usr/pgsql-14/include/ -I/usr/include/
LINK_DIR = -L/usr/pgsql-14/lib/ -L/usr/lib64/
LIB_DIR = -lpqxx -lpq -lpthread 
BUILD_DIR = ../build
DIST_DIR = ../dist
PROJECT_NAME = OronetaCoreServer

# Source code and object
SRCS = $(wildcard $(SRC_DIR)/*.cpp)
OBJS = $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS))

# Name of project
TARGET = $(DIST_DIR)/$(PROJECT_NAME)

# Compiler and options flag "no warning"
CC = g++
CFLAGS = -std=c++17 $(INC_DIR) $(LINK_DIR) $(LIB_DIR)

# Main executable program
all: $(TARGET)

# g++ --all
$(TARGET): $(OBJS)
	@mkdir -p $(DIST_DIR)
	$(CC) $(CFLAGS) $(OBJS) -o $(TARGET)

# g++ --code
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
	@mkdir -p $(BUILD_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

# Regla para limpiar
clean:
	rm -rf $(BUILD_DIR)/*.o $(TARGET) ../dist/*.tgz ../dist/*.tar
	

@tt4g
Copy link
Contributor

tt4g commented Apr 19, 2024

@ZhengLinLei If you specify CFLAGS = -std=c++17 in your project, you must specify -std=c++17 when building libpqxx.

-./configure --with-postgres-lib=/usr/pgsql-14/lib --with-postgres-include=/usr/pgsql-14/include
+./configure --with-postgres-lib=/usr/pgsql-14/lib --with-postgres-include=/usr/pgsql-14/include CXXFLAGS="-std=c++17"
 make && make install

And CC and CFLAGS are variables used for the C compiler.
When compiling C++, you should use CXX and CXXFLAGS.
Otherwise you will encounter strange errors.
See also: https://stackoverflow.com/questions/5541946/cflags-ccflags-cxxflags-what-exactly-do-these-variables-control

@jtv
Copy link
Owner

jtv commented Apr 19, 2024

We've had a lot of trouble with prepackaged libraries in part because no packaging system out there seems to take differences in compiler, compiler version, and C++ version into account. So it's easy to end up with incompatible binaries.

The other part is that the libpqxx exception class hierarchy had different ABIs depending on whether you compiled as C++17 or a newer version. And so you'd get link errors if you compiled the application and libpqxx as different C++ versions. But we changed that in 7.9.0.

@jtv
Copy link
Owner

jtv commented Apr 23, 2024

@ZhengLinLei any chance you could run grep -rI DEMANGLE in the directory where the libpqxx headers got installed?

I'd expect to see it defined. It's almost as if the libpqxx build itself isn't seeing the config header...

@jtv
Copy link
Owner

jtv commented May 13, 2024

In #828 we found that the real problem was a bad command line: in that case the compilation was done with g++ -lpqxx -lpq app.cxx. Changing it to g++ app.cxx -lpqxx -lpq solved the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants