问题
I have been looking for this issue on the internet, but can't find a solution. What I'm trying to achieve is to build a CGI-application with both dependencies of OpenSSL
and MySQLClient
.
When I compile my program, with the following command:
g++ -Wall -o test.cgi test.cpp -I/usr/include/mysql -lcgicc -lmysqlcppconn -lmysqlclient -lcurl -lnghttp2 -lssl -lcrypto -lpthread -ldl -DCURL_STATICLIB -std=c++11 -lz -static
I get the following error:
//usr/local/lib/libcrypto.a(err.o): In function `ERR_remove_thread_state':
err.c:(.text+0xe40): multiple definition of `ERR_remove_thread_state'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libmysqlclient.a(ssl.cpp.o):(.text+0x1df0): first defined here
I have tried multiple solutions, such as both down- and upgrade to other versions of OpenSSL, as opposed here. However, I still get this error when compiling with any of the following OpenSSL versions:
- OpenSSL 0.9.8
- OpenSSL 1.1.0g
- OpenSSL 1.1.1
What should I do to overcome this error and be able to compile my program statically?
回答1:
I looks like you are using an older MySQL (i.e., earlier than version 8).
In the earlier version, there is indeed a file ssl.cpp which defines ERR_remove_thread_state
void ERR_remove_thread_state(const void *)
{
GetErrors().Remove();
}
So, two approaches you can explore. (1) Try to upgrade to a more recent version of MySQL. or (2) build your own version of MySQL using the version as installed on you system, but rename this function to something else (i.e. edit the source code of MySQL before building it).
Update: a 3rd approach to attempt -- definitely in the realm of 'hacking' -- is to modify the libmysqlclient.a
to remove the offending symbol. This may or may-not work, but is fairly straight-forward to try.
To do this you need to take a copy of the libmysqlclient.a
and then unpack it (ar -x
). You should find an object file named ssl.cpp.o
. You can then list the symbols in that file (e.g., use something like readelf -s
), and confirm the ERR_remove_thread_state
is found. Then strip that symbol from that file (e.g. strip -N ERR_remove_thread_state ssl.cpp.o
), and then reassemble the object files back into the archive. Finally link statically to that modified archive, rather than the system one. Some caveats: because these are C++ files, you might need to use name demangling; and I've not tried this myself so unsure what consequences would be -- you would need to seriously test your application. The hope is that this symbol was not being used by any code paths, so removing it will allow successful compilation and application behaviour.
来源:https://stackoverflow.com/questions/57945558/g-compile-static-with-openssl-and-mysqlclient