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

pqxx library build error for crosscompiling on linux for Windows target with Mingw64 #336

Closed
yscontrol opened this issue Jun 14, 2020 · 38 comments

Comments

@yscontrol
Copy link

I built PostrgeSQL libpq (.dll, .a, ,..) v9.3.6 on ubuntu 14.04 and then tried building libpqxx v6.2.5 using cmake. It failed with error below:
[ 35%] Linking CXX shared library libpqxx.dll
CMakeFiles/pqxx_shared.dir/objects.a(connection_base.cxx.obj):connection_base.cxx:(.text+0x8eac): undefined reference to `__imp_select'
collect2: error: ld returned 1 exit status
make[2]: *** [src/libpqxx.dll] Error 1
make[1]: *** [src/CMakeFiles/pqxx_shared.dir/all] Error 2
make: *** [all] Error
Since PostgreSQL distro doers not have support for find_PQ.cmake, I replaced find_package with find_library and cmake funds static libpq.a while I am trying to build for .dll Windows
I am not sure how to figure out the issue. Changing versions to later is not desirable as I am porting code that works with v9.3.5 on linux (arm or x86).

@yscontrol yscontrol changed the title pqxx library build error for crosscompiling on linux for for Windows target with Mingw64 pqxx library build error for crosscompiling on linux for Windows target with Mingw64 Jun 14, 2020
@jtv
Copy link
Owner

jtv commented Jun 14, 2020

You should be able to use libpqxx 7.1 with postgres 9.3.5, just not with versions older than 9.3. You could even use a newer libpq with an older postgres server. There have been a lot of changes to the CMake build since libpqxx 6.2, so an upgrade may just solve this problem.

Another thing you can try is explicitly link to the Windows ws2_32 library. The configure build should do this automatically, but I'm not too sure about the CMake build.

@tt4g
Copy link
Contributor

tt4g commented Jun 15, 2020

@jtv is right.

As far as my search for "undefined reference to __imp_select'" goes, it seems to be a missing link to ws2_32`.

pqxx version 6.3.0 and above, ws2_32 is automatically added to the link target when the CMake target OS is Windows.
However, pqxx 6.2.5 does not automatically add it to the link target (this problem fixed by #126).

The following pqxx 6.3.0 permalink have been added for linking target (this code did not exist earlier than pqxx version 6.2.5):

if(WIN32)
target_link_libraries(${tgt} PUBLIC wsock32 ws2_32)
endif()

The best solution is to upgrade pqxx version.
Alternatively, add the same code as the above permalink to CMakeLists.txt in pqxx 6.2.5.

@yscontrol
Copy link
Author

yscontrol commented Jun 15, 2020 via email

@yscontrol
Copy link
Author

Could you please advise if my understanding of 7.1 build process is correct. I have to use custom location (not one of well-knowns) of PostgreSQL In both 6.2.5 and 7.1.0 the CMakeLists.txt attempts to find_package(PostgreSQL REQUIRED) but since it relies on cmake PostgreSQLConfig.cmake/ postgresql-config.cmake which are not provided with PostgreSQL as it does not have support for CMake fbuild. So custom file would need to be created to use libpqxx CMake build or path to modules would need to to change to avoid using cmake-3.17/Modules/ and use custom FindPostgreSQL/FindPQ.cmake. This is only needed for the sake of setting 1 (or 2 vars) PostgreSQL_LIBRARIES as PostgreSQL_INCLUDE_DIRS could be derived as ../include. So all this could have been done by using find_path or find_library with PATHS set to location of libpq.dll (or .a). Note, aside from this the find_package(PostgreSQL ..) is being called in multiple places config.cmake and src/CMakeLists.txt (plus 2 code locations in test) and I wonder why not in 1 place. I could bypass 2nd by setting PostgreSQL_FOUND

@yscontrol
Copy link
Author

yscontrol commented Jun 15, 2020

Now I realized I cant use 7.1 as it requires C++17 so I need to find one that allows C++1 .
Still question remains as I remove REQUIRED from find_package, use find_library to find libpq<.dll,.a,..> and set ``set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_LIBRARIES}/../include CACHE PATH "PostgreSQL_INCLUDE_DIR" FORCE)
set(PostgreSQL_FOUND TRUE CACHE BOOL "PostgreSQL package found" FORCE)
set(PostgreSQL_LIBRARIES ${PQSQL_LIBS} CACHE PATH "libraries needed for linking" FORCE)
set(PostgreSQL_VERSION_STRING "9.6.3" CACHE STRING "libpq version found" FORCE)`
I will have issue with cmake finding .a and then building static libpqxx for Windows. I wonder how to make sure it would build .dll and .lib

@tt4g
Copy link
Contributor

tt4g commented Jun 15, 2020

pqxx 7.1.0 required C++17 standard, you don't remove set(CMAKE_CXX_STANDARD 17).
and pqxx 7.x required libpq version 9.3.5 later.

@yscontrol
Copy link
Author

yscontrol commented Jun 15, 2020

Thx, but which one is latest supporting C++11 ? 6.4.0 seems it is

@tt4g
Copy link
Contributor

tt4g commented Jun 15, 2020

pqxx 6.4.0 (6.4.6 better) supports C++11 standard.

@yscontrol
Copy link
Author

ok, thx, still question of bypassing find_package and way of cross- building dll remains.
Also if I use ./configure I could specify path to pg_config but since PostreSQL was built on ubuntu for Windows I am not sure these version would be valid for cross compiling libpqxx,

@tt4g
Copy link
Contributor

tt4g commented Jun 15, 2020

Try set(PostgreSQL_INCLUDE_DIR <PATH_TO_INCLUDE_DIR>), set(PostgreSQL_TYPE_INCLUDE_DIR <PATH_TO_INCLUDE_DIR>) and set(PostgreSQL_LIBRARY <PATH_TO_LIBPQ>) to override find_package(PostgreSQL) result.

Example:

mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DPostgreSQL_LIBRARY="<PATH_TO_POSTGRES>/lib/libpq.lib" -DPostgreSQL_INCLUDE_DIR="<PATH_TO_INCLUDE_DIR>\include" -DPostgreSQL_TYPE_INCLUDE_DIR="<PATH_TO_INCLUDE_DIR>\include"
cmake --build . --config Debug --target -j 8

Another way, set(PostgreSQL_ROOT <PATH_TO_POSTGRES>).

mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DPostgreSQL_ROOT="<PATH_TO_POSTGRES>"
cmake --build . --config Debug --target -j 8

@yscontrol
Copy link
Author

yscontrol commented Jun 15, 2020

I just used find_library and set all necessary variables based on that:
set(PostgreSQL_INCLUDE_DIRS "${PostgreSQL_INCLUDE_DIRS}/include" CACHE PATH "PostgreSQL_INCLUDE_DIR" FORCE) set(PostgreSQL_FOUND TRUE CACHE BOOL "PostgreSQL package found" FORCE) set(PostgreSQL_LIBRARIES ${PQSQL_LIBS} CACHE PATH "libraries needed for linking" FORCE) set(PostgreSQL_VERSION_STRING "9.6.3" CACHE STRING "libpq version found" FORCE)
so they all set correctly. However I am getting error:
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting std::optional
-- Detecting std::optional - not supported
-- Detecting std::experimental::optional
-- Detecting std::experimental::optional - not supported
-- Detecting attribute ((const))
-- Detecting attribute ((const)) - supported
-- Detecting attribute ((pure))
-- Detecting attribute ((pure)) - supported
-- Detecting attribute ((visibility))
-- Detecting attribute ((visibility)) - supported
-- Generating config.h
-- Generating config.h - done
-- Configuring done
-- Generating done
-- Build files have been written ...
[ 1%] Building CXX object src/CMakeFiles/pqxx_shared.dir/connection.cxx.obj
In file included from /home/mydir/libpqxx/include/pqxx/basic_connection.hxx:23:0,
from /home/mydir/libpqxx/include/pqxx/connection.hxx:20,
from /home/mydir/libpqxx/include/pqxx/connection:12,
from /home/mydir/libpqxx/src/connection.cxx:20:
/home/mydir/libpqxx/include/pqxx/connection_base.hxx: In constructor ‘pqxx::connection_base::connection_base(pqxx::connectionpolicy&)’:
/home/mydir/libpqxx/include/pqxx/connection_base.hxx:739:14: error: invalid initialization of non-const reference of type ‘pqxx::connectionpolicy&’ from an rvalue of type ‘’
m_policy{pol}

SAme error with
git co 6.6.4 and 6.3.0.
In file included from /home/mydir/libpqxx/include/pqxx/basic_connection.hxx:23:0,
from /home/mydir/libpqxx/include/pqxx/connection.hxx:20,
from /home/mydir/libpqxx/include/pqxx/connection:6,
from /home/mydir/libpqxx/src/connection.cxx:20:
/home/mydir/libpqxx/include/pqxx/connection_base.hxx: In constructor ‘pqxx::connection_base::connection_base(pqxx::connectionpolicy&)’:
/home/mydir/libpqxx/include/pqxx/connection_base.hxx:739:14: error: invalid initialization of non-const reference of type ‘pqxx::connectionpolicy&’ from an rvalue of type ‘’
m_policy{pol}
^
make[2]: *** [src/CMakeFiles/pqxx_shared.dir/connection.cxx.obj] Error 1
make[1]: *** [src/CMakeFiles/pqxx_shared.dir/all] Error 2
make: *** [all] Error 2

NOTE: When I built PostgreSQL libpq.lib was not built only .dll, .a, .pc, .rc etc were built

@tt4g
Copy link
Contributor

tt4g commented Jun 16, 2020

What compiler and compiler version?

pqxx::connectionpolicy& argument of pqxx::connection_base constructor is provided by pqxx::basic_connection_base::m_policy.

Problem code:

explicit connection_base(connectionpolicy &pol) :
m_policy{pol}

Called by:

basic_connection_base() :
connection_base(m_policy),
m_options(std::string{}),
m_policy(m_options)
{ init(); }

But m_policy is member variable of pqxx::basic_connection_base, it should be able to be an lvalue.
This is not rvalue.

CONNECTPOLICY m_policy;

I ran a very similar code in Wandbox and was able to compile it: https://wandbox.org/permlink/OpB5Iqr9jaQb7sfc

It looks like a compiler problem.

@yscontrol
Copy link
Author

yscontrol commented Jun 16, 2020 via email

@yscontrol
Copy link
Author

Please also look at the question about building .dll & .lib for Windows rather than .a

@jtv
Copy link
Owner

jtv commented Jun 16, 2020

Isn't that a very old compiler?

By the way, MinGW might just be enough of a GNU environment that you could perhaps use the configure script instead.

But that's just me talking, as a not-a-CMake-expert. Thanks once again @tt4g for taking the reins where I'm out of my depth!

@yscontrol
Copy link
Author

yscontrol commented Jun 16, 2020

Switched to newer compiler , trying 5.3.0, 5.3.1
yes, I will try using configure but not sure what else do I need to install for that. The README.md says about configure "It needs to find the C header and the binary" but a) binary and headers are installed in different dirs under /usr b) postgresql-9.3.6 build has sources for pg_config but since this libpq build was done for Windows target, the executable is a Windows postgresql-9.3.6/./src/bin/pg_config/pg_config.exe and cant run on ubuntu so what exacly libpqxx needs for this case of crosscompilation?
I also noticed that config/sample-headers/compiler/compiler has only gcc-7.2 VisualStudio2013 dirs .
Lastly I am not clear with direction "the header files for PostgreSQL need the OpenSSL header files to be installed. If this happens". Where to, and how configure needs to be set to pick them . Again I built PostgreSQL ok without need to add any additional packages.

@yscontrol
Copy link
Author

yscontrol commented Jun 16, 2020

Build option Using configure(please add these option to --help) --with-postgres-include and --with-postgres-lib= ... set and configure completed with no errors.
However make in the same dir failed with the same error (among others) as cmake:
1st error in ../include/pqxx/internal/encodings.hxx:78:18: error: ‘callback’ has not been declared
^
../include/pqxx/internal/encodings.hxx: In function ‘void pqxx::internal::for_glyphs(pqxx::internal::encoding_group, int, const char*, std::basic_string::size_type, std::basic_string::size_type)’:
../include/pqxx/internal/encodings.hxx:92:42: error: there are no arguments to ‘callback’ that depend on a template parameter, so a declaration of ‘callback’ must be available [-fpermissive]
callback(buffer + here, buffer + next);
^
in template PQXX_LIBEXPORT inline void for_glyphs(
encoding_group enc,
CALLBACK callback,
const char buffer[],
std::string::size_type buffer_len,
std::string::size_type start = 0
)
Is not this is a problem in the code as missing realm of names dependent on template parameter? If no does not depend on template parameter, it must be resolvable in the first phase Two-Phase or Not Two-Phase:The Story of Dependent Names in Templates
And then error:
In file included from ../include/pqxx/nontransaction:12:0,
from connection_base.cxx:52:
../include/pqxx/nontransaction.hxx:66:59: error: within this context
namedclass{"nontransaction", Name}, transaction_base{C} { Begin(); }
^
../include/pqxx/nontransaction.hxx:66:59: error: cannot allocate an object of abstract type ‘pqxx::transaction_base’


...libpqxx$ make
Making all in include
make[1]: Entering directory /home/mydir/libpqxx/include' Making all in pqxx make[2]: Entering directory /home/mydir/libpqxx/include/pqxx'
make all-am
make[3]: Entering directory /home/mydir/libpqxx/include/pqxx' make[3]: Leaving directory /home/mydir/libpqxx/include/pqxx'
make[2]: Leaving directory /home/mydir/libpqxx/include/pqxx' make[2]: Entering directory /home/mydir/libpqxx/include'
make[2]: Nothing to be done for all-am'. make[2]: Leaving directory /home/mydir/libpqxx/include'
make[1]: Leaving directory /home/mydir/libpqxx/include' Making all in src make[1]: Entering directory /home/mydir/libpqxx/src'
/bin/sh ../libtool --tag=CXX --mode=compile x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT array.lo -MD -MP -MF .deps/array.Tpo -c -o array.lo array.cxx
libtool: compile: x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT array.lo -MD -MP -MF .deps/array.Tpo -c array.cxx -o array.o
mv -f .deps/array.Tpo .deps/array.Plo
/bin/sh ../libtool --tag=CXX --mode=compile x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT binarystring.lo -MD -MP -MF .deps/binarystring.Tpo -c -o binarystring.lo binarystring.cxx
libtool: compile: x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT binarystring.lo -MD -MP -MF .deps/binarystring.Tpo -c binarystring.cxx -o binarystring.o
mv -f .deps/binarystring.Tpo .deps/binarystring.Plo
/bin/sh ../libtool --tag=CXX --mode=compile x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT connection_base.lo -MD -MP -MF .deps/connection_base.Tpo -c -o connection_base.lo connection_base.cxx
libtool: compile: x86_64-w64-mingw32-g++ -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT connection_base.lo -MD -MP -MF .deps/connection_base.Tpo -c connection_base.cxx -o connection_base.o
In file included from ../include/pqxx/result.hxx:27:0,
from ../include/pqxx/binarystring.hxx:20,
from ../include/pqxx/binarystring:10,
from connection_base.cxx:49:
../include/pqxx/internal/encodings.hxx:78:18: error: ‘callback’ has not been declared
CALLBACK callback,
^
../include/pqxx/internal/encodings.hxx: In function ‘void pqxx::internal::for_glyphs(pqxx::internal::encoding_group, int, const char*, std::basic_string::size_type, std::basic_string::size_type)’:
../include/pqxx/internal/encodings.hxx:92:42: error: there are no arguments to ‘callback’ that depend on a template parameter, so a declaration of ‘callback’ must be available [-fpermissive]
callback(buffer + here, buffer + next);
^
../include/pqxx/internal/encodings.hxx:92:42: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
In file included from ../include/pqxx/connection_base.hxx:26:0,
from ../include/pqxx/basic_connection.hxx:23,
from ../include/pqxx/connection.hxx:20,
from ../include/pqxx/connection:12,
from connection_base.cxx:50:
../include/pqxx/prepared_statement.hxx: At global scope:
../include/pqxx/prepared_statement.hxx:84:78: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED invocation(transaction_base &, const std::string &statement);
^
In file included from ../include/pqxx/basic_connection.hxx:23:0,
from ../include/pqxx/connection.hxx:20,
from ../include/pqxx/connection:12,
from connection_base.cxx:50:
../include/pqxx/connection_base.hxx:178:33: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED void activate(); //[t12]
^
../include/pqxx/connection_base.hxx:189:35: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED void deactivate(); //[t12]
^
../include/pqxx/connection_base.hxx:236:57: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED void inhibit_reactivation(bool inhibit) //[t86]
^
../include/pqxx/connection_base.hxx:601:65: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED void perform(const TRANSACTOR &T, int Attempts); //[t04]
^
../include/pqxx/connection_base.hxx:611:51: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED void perform(const TRANSACTOR &T)
^
In file included from ../include/pqxx/basic_connection.hxx:23:0,
from ../include/pqxx/connection.hxx:20,
from ../include/pqxx/connection:12,
from connection_base.cxx:50:
../include/pqxx/connection_base.hxx:805:5: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
int);
^
../include/pqxx/connection_base.hxx:896:13: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
int nparams);
^
../include/pqxx/connection_base.hxx: In constructor ‘pqxx::connection_base::connection_base(pqxx::connectionpolicy&)’:
../include/pqxx/connection_base.hxx:739:14: error: invalid initialization of non-const reference of type ‘pqxx::connectionpolicy&’ from an rvalue of type ‘’
m_policy{pol}
^
In file included from ../include/pqxx/connection.hxx:20:0,
from ../include/pqxx/connection:12,
from connection_base.cxx:50:
../include/pqxx/basic_connection.hxx: At global scope:
../include/pqxx/basic_connection.hxx:91:39: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED basic_connection() =default;
^
../include/pqxx/basic_connection.hxx:92:67: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED explicit basic_connection(const std::string &opt) :
^
../include/pqxx/basic_connection.hxx:94:61: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED explicit basic_connection(const char opt[]) :
^
../include/pqxx/basic_connection.hxx:97:59: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
PQXX_DEPRECATED explicit basic_connection(std::nullptr_t) :
^
In file included from ../include/pqxx/nontransaction.hxx:21:0,
from ../include/pqxx/nontransaction:12,
from connection_base.cxx:52:
../include/pqxx/transaction_base.hxx: In constructor ‘pqxx::internal::transactionfocus::transactionfocus(pqxx::transaction_base&)’:
../include/pqxx/transaction_base.hxx:49:23: error: invalid initialization of non-const reference of type ‘pqxx::transaction_base&’ from an rvalue of type ‘’
m_registered{false}
^
../include/pqxx/transaction_base.hxx: At global scope:
../include/pqxx/transaction_base.hxx:77:45: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
connection_base &, const std::string &query);
^
../include/pqxx/transaction_base.hxx:366:41: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
parameterized(const std::string &query);
^
../include/pqxx/transaction_base.hxx:475:54: warning: ‘deprecated’ attribute directive ignored [-Wattributes]
prepared(const std::string &statement=std::string{});
^
../include/pqxx/transaction_base.hxx: In constructor ‘pqxx::nontransaction::nontransaction(pqxx::connection_base&, const string&)’:
../include/pqxx/transaction_base.hxx:524:12: error: ‘pqxx::transaction_base::transaction_base(pqxx::connection_base&, bool)’ is protected
explicit transaction_base(connection_base &c, bool direct=true);
^
In file included from ../include/pqxx/nontransaction:12:0,
from connection_base.cxx:52:
../include/pqxx/nontransaction.hxx:66:59: error: within this context
namedclass{"nontransaction", Name}, transaction_base{C} { Begin(); }
^
../include/pqxx/nontransaction.hxx:66:59: error: cannot allocate an object of abstract type ‘pqxx::transaction_base’
In file included from ../include/pqxx/nontransaction.hxx:21:0,
from ../include/pqxx/nontransaction:12,
from connection_base.cxx:52:
../include/pqxx/transaction_base.hxx:136:36: note: because the following virtual functions are pure within ‘pqxx::transaction_base’:
class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
^
../include/pqxx/transaction_base.hxx:147:11: note: virtual pqxx::transaction_base::~transaction_base()
virtual ~transaction_base() =0; //[t01]
^
../include/pqxx/transaction_base.hxx:535:16: note: virtual void pqxx::transaction_base::do_begin()
virtual void do_begin() =0;
^
../include/pqxx/transaction_base.hxx:537:18: note: virtual pqxx::result pqxx::transaction_base::do_exec(const char*)
virtual result do_exec(const char Query[]) =0;
^
../include/pqxx/transaction_base.hxx:539:16: note: virtual void pqxx::transaction_base::do_commit()
virtual void do_commit() =0;
^
../include/pqxx/transaction_base.hxx:541:16: note: virtual void pqxx::transaction_base::do_abort()
virtual void do_abort() =0;
^
connection_base.cxx: In member function ‘std::string pqxx::connection_base::esc_like(const string&, char) const’:
connection_base.cxx:1163:12: error: no matching function for call to ‘for_glyphs(pqxx::internal::encoding_group, pqxx::connection_base::esc_like(const string&, char) const::__lambda1, const char*, std::basic_string::size_type)’
str.size());
^
connection_base.cxx:1163:12: note: candidate is:
In file included from ../include/pqxx/result.hxx:27:0,
from ../include/pqxx/binarystring.hxx:20,
from ../include/pqxx/binarystring:10,
from connection_base.cxx:49:
../include/pqxx/internal/encodings.hxx:76:56: note: template void pqxx::internal::for_glyphs(pqxx::internal::encoding_group, int, const char*, std::basic_string::size_type, std::basic_string::size_type)
template PQXX_LIBEXPORT inline void for_glyphs(
^
../include/pqxx/internal/encodings.hxx:76:56: note: template argument deduction/substitution failed:
connection_base.cxx:1163:12: note: cannot convert ‘pqxx::connection_base::esc_like(const string&, char) const::__lambda1{(* & out), escape_char}’ (type ‘pqxx::connection_base::esc_like(const string&, char) const::__lambda1’) to type ‘int’
str.size());
^
connection_base.cxx: In constructor ‘pqxx::internal::reactivation_avoidance_exemption::reactivation_avoidance_exemption(pqxx::connection_base&)’:
connection_base.cxx:1173:21: error: invalid initialization of non-const reference of type ‘pqxx::connection_base&’ from an rvalue of type ‘’
m_open{C.is_open()}
^
connection_base.cxx: In function ‘void pqxx::internal::wait_read(const PGconn*, long int, long int)’:
connection_base.cxx:1260:53: warning: narrowing conversion of ‘(time_t)seconds’ from ‘time_t {aka long long int}’ to ‘long int’ inside { } [-Wnarrowing]
timeval tv = { time_t(seconds), int(microseconds) };
^
make[1]: *** [connection_base.lo] Error 1
make[1]: Leaving directory `/home/mydir/libpqxx/src'
make: *** [all-recursive] Error 1

@tt4g
Copy link
Contributor

tt4g commented Jun 16, 2020

Is not this is a problem in the code as missing realm of names dependent on template parameter?

@yscontrol Did you build pqxx 6.3.0? If so, Update pqxx 6.3.1 because this issue fixed: #153

@yscontrol
Copy link
Author

yes, I upgraded to 6.4.6 and this issue went away. However we are back with the original issue:
^
../include/pqxx/connection_base.hxx: In constructor ‘pqxx::connection_base::connection_base(pqxx::connectionpolicy&)’:
../include/pqxx/connection_base.hxx:739:14: error: invalid initialization of non-const reference of type ‘pqxx::connectionpolicy&’ from an rvalue of type ‘’
m_policy{pol}
^

@tt4g
Copy link
Contributor

tt4g commented Jun 17, 2020

@yscontrol I found the following issue reports:

It seems to be a bug brought about by the C++11 standard.
It has been modified by the C++14 standard.
And although gcc 4 is affected by this bug, it doesn't seem to be a problem if you use gcc 5 (see eXpl0it3r/SmallGameEngine#3).

@tt4g
Copy link
Contributor

tt4g commented Jun 17, 2020

I can reproduce " invalid initialization of non-const reference of type ..." error with gcc 4.8.5: https://wandbox.org/permlink/mQr8Olis4MLXrH8O

When using gcc 4.9.3, I can compile same code: https://wandbox.org/permlink/aKrhTuuctUA1JUBl

@yscontrol There are two solutions.
The first is to update gcc to at least version 4.9.
The second is to apply a patch that replaces all of the List-initialization in the source code with parentheses.

Example:

protected:
  explicit connection_base(connectionpolicy &pol) :
-	m_policy{pol}
+	m_policy(pol)

@yscontrol
Copy link
Author

yscontrol commented Jun 17, 2020 via email

@tt4g
Copy link
Contributor

tt4g commented Jun 17, 2020

From reading the comments on the above link, I'd say that up to gcc 4.8, It was in compliance with the FDIS (final draft international standard) of C++ standard specification.
gcc 4.8 seemed to behave in accordance with FDIS.
However, problems like this issue have been reported and C++ standard specification has been corrected.
gcc 4.9 and later seemed to behave in accordance with fixed C++ standard specification.

@yscontrol
Copy link
Author

yscontrol commented Jun 17, 2020

Many thanks for your investigation, tt4g. I tried changing instances flagged above and other places causing error got next error in the code:
include/pqxx/transaction_base.hxx:524
protected:
/// Create a transaction (to be called by implementation classes only)
/** The optional name, if nonempty, must begin with a letter and may contain

  • letters and digits only.
  • @param c The connection that this transaction is to act on.
  • @param direct Running directly in connection context (i.e. not nested)?
    */
    explicit transaction_base(connection_base &c, bool direct=true);
    ^
    ../include/pqxx/transaction_base.hxx: In constructor ‘pqxx::dbtransaction::dbtransaction(pqxx::connection_base&, const string&, pqxx::readwrite_policy)’:
    ../include/pqxx/transaction_base.hxx:524:12: error: ‘pqxx::transaction_base::transaction_base(pqxx::connection_base&, bool)’ is protected
    explicit transaction_base(connection_base &c, bool direct=true);
    ^
    dbtransaction.cxx:45:60: error: within this context
    m_start_cmd{generate_set_transaction(rw, IsolationString)}

-So for the sake of compiling I made it public and got next error:
in dbtransaction.cxx
pqxx::dbtransaction::dbtransaction(
connection_base &C,
const std::string &IsolationString,
readwrite_policy rw) :
namedclass{"dbtransaction"},
transaction_base{C}, // <---reference to pure virtual
m_start_cmd{generate_set_transaction(rw, IsolationString)} //<- same error if {}->()
{
}

pqxx::dbtransaction::dbtransaction(
connection_base &C,
bool direct,
readwrite_policy rw) :
namedclass{"dbtransaction"},
transaction_base(C, direct), // <---reference to pure virtual
m_start_cmd{generate_set_transaction(rw)}
{
}

and in ./include/pqxx/transaction_base.hxx
class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
public virtual internal::namedclass
{
public:
/// If nothing else is known, our isolation level is at least read_committed
using isolation_tag = isolation_traits<read_committed>;
transaction_base() =delete;
transaction_base(const transaction_base &) =delete;
transaction_base &operator=(const transaction_base &) =delete;
virtual ~transaction_base() =0; // <--pure virt
// indeed pure virtual
Error:
dbtransaction.cxx: In constructor ‘pqxx::dbtransaction::dbtransaction(pqxx::connection_base&, const string&, pqxx::readwrite_policy)’:
dbtransaction.cxx:45:60: error: cannot allocate an object of abstract type ‘pqxx::transaction_base’
m_start_cmd{generate_set_transaction(rw, IsolationString)}
^
In file included from ../include/pqxx/dbtransaction.hxx:19:0,
from ../include/pqxx/dbtransaction:6,
from dbtransaction.cxx:13:
../include/pqxx/transaction_base.hxx:136:36: note: because the following virtual functions are pure within ‘pqxx::transaction_base’:
class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
^
../include/pqxx/transaction_base.hxx:147:11: note: virtual pqxx::transaction_base::~transaction_base()
virtual ~transaction_base() =0; //[t01]
^
../include/pqxx/transaction_base.hxx:535:16: note: virtual void pqxx::transaction_base::do_begin()
virtual void do_begin() =0;
^
../include/pqxx/transaction_base.hxx:537:18: note: virtual pqxx::result pqxx::transaction_base::do_exec(const char*)
virtual result do_exec(const char Query[]) =0;
^
../include/pqxx/transaction_base.hxx:539:16: note: virtual void pqxx::transaction_base::do_commit()
virtual void do_commit() =0;
^
../include/pqxx/transaction_base.hxx:541:16: note: virtual void pqxx::transaction_base::do_abort()
virtual void do_abort() =0;
^
make[1]: *** [dbtransaction.lo] Error 1

@jtv
Copy link
Owner

jtv commented Jun 17, 2020

Have you tried removing the PQXX_NOVTABLE? The error as given is definitely nonsensical — you can't allocate an object of an abstract type, but of course you should be able to base-class-initialise it.

@yscontrol
Copy link
Author

How do I do that safely? I see
./include/pqxx/robusttransaction.hxx:30:class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction :
./include/pqxx/dbtransaction.hxx:62:class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base
./include/pqxx/tablestream.hxx:26:class PQXX_LIBEXPORT PQXX_NOVTABLE tablestream :
./include/pqxx/notification.hxx:55:class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver
./include/pqxx/stream_base.hxx:27:class PQXX_LIBEXPORT PQXX_NOVTABLE stream_base :
./include/pqxx/compiler-public.hxx:60:#define PQXX_NOVTABLE __declspec(novtable)
./include/pqxx/compiler-public.hxx:118:#ifndef PQXX_NOVTABLE
./include/pqxx/compiler-public.hxx:119:#define PQXX_NOVTABLE
./include/pqxx/transaction_base.hxx:136:class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
./include/pqxx/except.hxx:55:class PQXX_LIBEXPORT PQXX_NOVTABLE pqxx_exception
./doc/Doxyfile.in:1058: PQXX_NOVTABLE= \

@jtv
Copy link
Owner

jtv commented Jun 17, 2020

It's possible that in your case it already happens, but the simplest way to make sure would be to edit compiler-public.hxx, and in line 60, remove the __declspec(novtable) part of the line.

@yscontrol
Copy link
Author

yscontrol commented Jun 17, 2020

no, line 60 is under _MSC_VER while I am cross-compiling on linux for Windows
// Workarounds for Microsoft Visual C++
#ifdef _MSC_VER
// Suppress vtables on abstract classes.
#define PQXX_NOVTABLE __declspec(novtable)

@yscontrol
Copy link
Author

yscontrol commented Jun 17, 2020

meanwhile, I tried to build with newer compiler:
x86_64-w64-mingw32-g++ (GCC) 5.3.1 20160211
x86_64-w64-mingw32-gcc (GCC) 5.3.1 20160211
and I am getting error:
/bin/bash ../libtool --tag=CXX --mode=compile /usr/bin/x86_64-w64-mingw32-gcc -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT util.lo -MD -MP -MF .deps/util.Tpo -c -o util.lo util.cxx
libtool: compile: /usr/bin/x86_64-w64-mingw32-gcc -std=c++11 -DHAVE_CONFIG_H -I../include -I../include -I/home/mydir/postgresql-9.3.6/install/mingw64/include -g -O2 -fvisibility=hidden -fvisibility-inlines-hidden -MT util.lo -MD -MP -MF .deps/util.Tpo -c util.cxx -o util.o
util.cxx: In function ‘void pqxx::internal::sleep_seconds(int)’:
util.cxx:120:8: error: ‘std::this_thread’ has not been declared
std::this_thread::sleep_for(std::chrono::seconds(s));
^
Makefile:524: recipe for target 'util.lo' failed
So I need to address this with mingw and still focus on PQXX_NOVTABLE error

@tt4g
Copy link
Contributor

tt4g commented Jun 18, 2020

util.cxx:120:8: error: ‘std::this_thread’ has not been declared
std::this_thread::sleep_for(std::chrono::seconds(s));
^

That' s MinGW problem.
MinGW does not support C++11 thread feature on Windows OS.

Maybe this solution will help you: apt - How do I install mingw-std-threads on Ubuntu? - Unix & Linux Stack Exchange

Another solutions:

@yscontrol
Copy link
Author

yscontrol commented Jun 18, 2020

tt4g, thank you very much , I will have to use cmake /modify libpqxx to include https://github.com/meganz/mingw-std-threads header only lib. However the main approach still requires use of ubuntu 14.04 - gcc 4.8.2 and so resolving issue with "dbtransaction.cxx:45:60: error: cannot allocate an object of abstract type ‘pqxx::transaction_base’
m_start_cmd{generate_set_transaction(rw, IsolationString)}" above or removing the PQXX_NOVTABLE ?

@tt4g
Copy link
Contributor

tt4g commented Jun 18, 2020

removing the PQXX_NOVTABLE ?

Yes. replace #define PQXX_NOVTABLE __declspec(novtable) with#define PQXX_NOVTABLE.

__declspec(novtable) is an extended attribute that, if present, will cause a runtime error. It won't matter if you remove it.

@jtv has commented on that as well.: #336 (comment)

@yscontrol
Copy link
Author

yscontrol commented Jun 18, 2020

@jtv Thank you but such change would not have any effect because
line 60
./include/pqxx/compiler-public.hxx:60:#define PQXX_NOVTABLE __declspec(novtable)

is under _MSC_VER while I am cross-compiling on Linux for Windows
// Workarounds for Microsoft Visual C++
#ifdef _MSC_VER
// Suppress vtables on abstract classes.
#define PQXX_NOVTABLE __declspec(novtable)

@jtv
Copy link
Owner

jtv commented Jun 18, 2020

@yscontrol yes, I'm just bringing it up because sometimes the lines between "Windows" and "MSVC" get a little blurred. And I've got no other idea why gcc (even version 2.7 if it came to that!) would object to base-class-initialising an abstract class!

@yscontrol
Copy link
Author

@jtv @tt4g , thanks but is there an easy way to bypass problematic code without losing main functionality?

@jtv
Copy link
Owner

jtv commented Jun 18, 2020

It all depends. If threading is the problem, 7.x can build without thread support. In 6.4 I think you could just remove the two instances of the keyword thread_local in src/strconv.cxx, and it'll be slower but still work otherwise.

@jtv
Copy link
Owner

jtv commented Jun 30, 2020

@yscontrol are we done with this ticket? I'm trying to clean up a bit so we can keep a good overview of what the problems are.

@yscontrol
Copy link
Author

yscontrol commented Jul 14, 2020

Thank you for your support, but based on more resent attempts to build with different build parameters I think suggested code change (Yes. replace #define PQXX_NOVTABLE __declspec(novtable) with#define PQXX_NOVTABLE.) would be unnecessary with mingw64 gcc 5.3.0/5.3.1

jtv added a commit that referenced this issue Apr 24, 2021
Fixes #336, #398, #424, #441

For years now, MinGW has had trouble compiling files which
`#include <thread>`.  The exact errors seem to have evolved over that
time, but MinGW users still can't compile libpqxx without editing the
standard header.

Luckily we don't use this header much yet.  It's just `sleep_for()`.  We
used to have our own function for this, which would use one of a bunch
of platform-specific alternatives.  I basically revived it, except that
`sleep_for` is in `std` and most compilers implement it, so it's
basically MinGW versus everyone else.  And therefore, we really only
need the one alternate implementation.
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