taocpp / taopq

C++ client library for PostgreSQL
Boost Software License 1.0
264 stars 40 forks source link

Compile error with MSYS2 and GCC #7

Closed junjiexing closed 6 years ago

junjiexing commented 6 years ago

Compile command:

git clone https://github.com/taocpp/postgres.git taocpp_pg
cd taocpp_pg
mkdir build&&cd build
cmake ../ -G "MSYS Makefiles"
make

Output:

Scanning dependencies of target taocpp-postgres
[  3%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/connection.cpp.obj
[  6%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/connection_pool.cpp.obj
[ 10%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/field.cpp.obj
[ 13%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/result.cpp.obj
[ 17%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/result_traits.cpp.obj
[ 20%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/row.cpp.obj
[ 24%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/table_writer.cpp.obj
[ 27%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/postgres/transaction.cpp.obj
[ 31%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/utility/demangle.cpp.obj
[ 34%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/utility/getenv.cpp.obj
[ 37%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/utility/printf.cpp.obj
[ 41%] Building CXX object CMakeFiles/taocpp-postgres.dir/src/lib/utility/strtox.cpp.obj
[ 44%] Linking CXX static library libtaocpp-postgres.a
[ 44%] Built target taocpp-postgres
Scanning dependencies of target transaction
[ 48%] Building CXX object src/test/postgres/CMakeFiles/transaction.dir/transaction.cpp.obj
[ 51%] Linking CXX executable transaction.exe
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x18): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIavE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x18): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x28): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIhvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x28): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x38): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIsvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x38): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x48): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsItvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x48): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x58): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIivE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x58): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x68): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIjvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x68): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x78): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIlvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x78): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x88): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsImvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x88): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0x98): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIxvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0x98): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0xa8): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIyvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0xa8): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0xb8): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIfvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0xb8): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0xc8): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIdvE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0xc8): first defined here
../../../libtaocpp-postgres.a(transaction.cpp.obj):transaction.cpp:(.rdata+0xd8): multiple definition of `.weak._ZN3tao8postgres16parameter_traitsIevE6formatE._ZNSt9exceptionC2Ev'
../../../libtaocpp-postgres.a(connection.cpp.obj):connection.cpp:(.rdata+0xd8): first defined here
collect2.exe: error: ld returned 1 exit status
make[2]: *** [src/test/postgres/CMakeFiles/transaction.dir/build.make:98:src/test/postgres/transaction.exe] 错误 1
make[1]: *** [CMakeFiles/Makefile2:137:src/test/postgres/CMakeFiles/transaction.dir/all] 错误 2
make: *** [Makefile:141:all] 错误 2

It seems that the static variable "format" at there is not defined in the cpp file.

d-frey commented 6 years ago

The problem is not that it is not defined in the cpp file, the problem is that it is defined multiple times in the header. Which should be OK if I mark it as a weak symbol, but apparently your environment (MSYS? MSYS2?) does accept the __attribute__(( weak )), but then decides to ignore it.

What makes the situation worse is that I already tried to find a common solution which would be accepted by all compilers, versions, and environments and especially Clang and MSVC seem to have very different ideas of what the code should look like. It's not an easy problem.

I'll try again to solve this and maybe get rid of the format variables altogether, at the cost of duplicating quite a bit of code. We'll see... :)

d-frey commented 6 years ago

I've committed a fix by manually unrolling the template specializations. Let's see how the CI reacts, meanwhile could you please check if it also solves the problem in your environment? Re-open the issue if necessary. Thanks!

junjiexing commented 6 years ago

Now I got a compile error, not a link error:

[ 48%] Building CXX object src/test/postgres/CMakeFiles/transaction.dir/transaction.cpp.obj
In file included from D:/Project/Cpp/taocpp_pg/include/tao/postgres/transaction.hpp:13:0,
                 from D:/Project/Cpp/taocpp_pg/include/tao/postgres/connection.hpp:13,
                 from D:/Project/Cpp/taocpp_pg/src/test/postgres/transaction.cpp:6:
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp: In constructor 'tao::postgres::parameter_traits<signed char>::parameter_traits(signed char)':
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:149:57: error: unknown conversion type character 'h' in format [-Werror=format=]
             : string_helper( utility::printf( "%hhd", v ) )
                                                         ^
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:149:57: error: too many arguments for format [-Werror=format-extra-args]
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp: In constructor 'tao::postgres::parameter_traits<unsigned char>::parameter_traits(unsigned char)':
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:159:57: error: unknown conversion type character 'h' in format [-Werror=format=]
             : string_helper( utility::printf( "%hhu", v ) )
                                                         ^
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:159:57: error: too many arguments for format [-Werror=format-extra-args]
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp: In constructor 'tao::postgres::parameter_traits<long long int>::parameter_traits(long long int)':
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:229:57: error: unknown conversion type character 'l' in format [-Werror=format=]
             : string_helper( utility::printf( "%lld", v ) )
                                                         ^
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:229:57: error: too many arguments for format [-Werror=format-extra-args]
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp: In constructor 'tao::postgres::parameter_traits<long long unsigned int>::parameter_traits(long long unsigned int)':
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:239:57: error: unknown conversion type character 'l' in format [-Werror=format=]
             : string_helper( utility::printf( "%llu", v ) )
                                                         ^
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:239:57: error: too many arguments for format [-Werror=format-extra-args]
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp: In constructor 'tao::postgres::parameter_traits<long double>::parameter_traits(long double)':
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:269:59: error: unknown conversion type character 'L' in format [-Werror=format=]
             : string_helper( utility::printf( "%.21Lg", v ) )
                                                           ^
D:/Project/Cpp/taocpp_pg/include/tao/postgres/parameter_traits.hpp:269:59: error: too many arguments for format [-Werror=format-extra-args]
cc1plus.exe: all warnings being treated as errors
make[2]: *** [src/test/postgres/CMakeFiles/transaction.dir/build.make:63:src/test/postgres/CMakeFiles/transaction.dir/transaction.cpp.obj] 错误 1
make[1]: *** [CMakeFiles/Makefile2:137:src/test/postgres/CMakeFiles/transaction.dir/all] 错误 2
make: *** [Makefile:141:all] 错误 2

My environment is MSYS2, and gcc version is 7.3.0. But when I use the same version gcc on archlinux to compile it, there is no problem. I don't know what's the problem.

d-frey commented 6 years ago

Quick googling turned up this: https://github.com/msys2/msys2/wiki/Porting#c-printf-format-specifier-issues

See if setting __USE_MINGW_ANSI_STDIO=1 helps. I currently don't have the time to support MSYS2 myself, if you could figure out a solution I'd be happy to hear about it.

junjiexing commented 6 years ago

I try to add add_definitions(-D__USE_MINGW_ANSI_STDIO=1) to CMakeLists.txt, but has no effective, and I did not find an effective solution to this problem😞. Finally I removed the Werror compile option.