Closed ZhengLinLei closed 1 month ago
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?
It use by default C++17 for the compilation. Also I tried changing it to C++20 but doesn't work.
If the compile options match, then there may be another version libpqxx installed on the machine and the linker links to it.
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
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.
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*)'
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
?
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 theDockerfile
?
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
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.
A will try to find any other solution to fix this using other OS image or using libpq++. Thanks for helping me. 😄
@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.
@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 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
Include
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.
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
@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
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.
@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...
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.
I'm having troubles compiling my project. It shows undefined references error.
Information:
Problem
When I try to compile the project with:
I have this error: