Closed Herz3h closed 6 years ago
Never mind regarding the Redefinition error, I had <client/ovncli.hpp> included two times in different files. But now it tells me OPENVPN_PACKAGE_ID must be defined. And this turns out to be in the Android folder.
I intend to build application for OS X and Windows only, what am I doing wrong ?
we don't know what you are doing therefore it is not easy to guess what's wrong. How about you share how you are compiling the library/binary and what is the exact output with the error?
Okay here is the compilation line which Qt generates :
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -c -pipe -stdlib=libc++ -fwhole-program -O3 -Wno-sign-compare -Wno-unused-parameter -arch x86_64 -std=c++11 -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden -DUSE_MBEDTLS -DUSE_ASIO -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -w -g -std=gnu++11 -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -mmacosx-version-min=10.10 -Wall -W -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I../VPNGUI-I. -I../VPNGUI/src/ovpn3/core -I../VPNGUI/src/mac/mbedtls/mbedtls-osx/include -I../VPNGUI/src/mac/asio/asio/include -I../VPNGUI/src/mac/lz4/lz4-osx/include -I../../Qt/5.10.1/clang_64/lib/QtWidgets.framework/Headers -I../../Qt/5.10.1/clang_64/lib/QtGui.framework/Headers -I../../Qt/5.10.1/clang_64/lib/QtNetwork.framework/Headers -I../../Qt/5.10.1/clang_64/lib/QtCore.framework/Headers -I. -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/OpenGL.framework/Headers -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/AGL.framework/Headers -I../../Qt/5.10.1/clang_64/mkspecs/macx-clang -F/Users/Herz3h/Qt/5.10.1/clang_64/lib -o main.o ../VPNGUI/main.cpp
And here is compilation error:
In file included from ../VPNGUI/src/ovpn3/core/openvpn/options/merge.hpp:36: ../VPNGUI/src/ovpn3/core/openvpn/common/options.hpp:1290:37: error: reference to overloaded function could not be resolved; did you mean to call it? OPENVPN_LOG_NTNL(title << std::endl << render(Option::RENDER_TRUNC_64|Option::RENDER_NUMBER|Option::RENDER_BRACKET|Option::RENDER_UNUSED));
Finally here is the class code that includes openvpn header files:
#ifndef CLIENT_H
#define CLIENT_H
#include <openvpn/options/merge.hpp>
#include <client/ovpncli.cpp>
using namespace openvpn::ClientAPI;
class Client : public OpenVPNClient
{
public:
Client();
virtual bool socket_protect(int socket) override;
virtual bool pause_on_connection_timeout() override;
// Callback for delivering events during connect() call.
// Will be called from the thread executing connect().
virtual void event(const Event&) override;
// Callback for logging.
// Will be called from the thread executing connect().
virtual void log(const LogInfo&) override;
// External PKI callbacks
// Will be called from the thread executing connect().
virtual void external_pki_cert_request(ExternalPKICertRequest&) override;
virtual void external_pki_sign_request(ExternalPKISignRequest&) override;
private:
// openvpn::ProfileMerge *profileMerge;
// Config *config;
};
#endif // CLIENT_H
Note: I have followed compilation guide for mac, then moved the src folder to my project folder and finally added options dans the build script (build cli command) adds when it generates the command.
Try adding #include <openvpn/common/platform.hpp>
first and then move #include <client/ovpncli.cpp>
above the openvpn/options/merge.hpp
include.
I have a new error now :
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -dynamic -arch x86_64 -headerpad_max_install_names -macosx_version_min 10.10.0 -o vpn-bridge.app/Contents/MacOS/vpn-bridge -L/Users/Herz3h/Documents/VPNGUI-WINDOWS/src/mac/mbedtls/mbedtls-osx/library -framework Security -framework CoreFoundation -framework SystemConfiguration -framework IOKit -framework ApplicationServices -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -rpath @executable_path/Frameworks -rpath /Users/Herz3h/Qt/5.10.1/clang_64/lib main.o mainwindow.o client.o qrc_logojpl.o moc_mainwindow.o -lmbedtls /Users/Herz3h/Documents/VPNGUI-WINDOWS/src/mac/lz4/lz4-osx/lib/liblz4.a -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework QtNetwork -framework OpenGL -framework AGL -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.1.0/lib/darwin/libclang_rt.osx.a -F/Users/Herz3h/Qt/5.10.1/clang_64/lib
duplicate symbol __ZN7openvpn9ClientAPI13OpenVPNClient16crypto_self_testEv in:
main.o
mainwindow.o
duplicate symbol __ZN7openvpn9ClientAPI13OpenVPNClient9copyrightEv in:
main.o
mainwindow.o
duplicate symbol __ZN7openvpn9ClientAPI13OpenVPNClient13on_disconnectEv in:
main.o
mainwindow.o
The errors keeps going on, I seem to have 204 duplicated symbols. I made sure I included ovpncli.cpp only once in my .h file
Edit: This was apparently caused because I included ovpncli.cpp
in one h file, which is then included in two .cpp files. So I have changed the ovpncli.cpp
to ovpncli.hpp
But now I have the same error as my previous post (same file and line and same error).
This is what I have in my .h file :
#ifndef CLIENT_H
#define CLIENT_H
#include <openvpn/common/platform.hpp>
#include <client/ovpncli.hpp>
#include <openvpn/options/merge.hpp>
using namespace openvpn::ClientAPI;
class Client : public OpenVPNClient
{
public:
Client();
virtual bool socket_protect(int socket) override;
virtual bool pause_on_connection_timeout() override;
// Callback for delivering events during connect() call.
// Will be called from the thread executing connect().
virtual void event(const Event&) override;
// Callback for logging.
// Will be called from the thread executing connect().
virtual void log(const LogInfo&) override;
// External PKI callbacks
// Will be called from the thread executing connect().
virtual void external_pki_cert_request(ExternalPKICertRequest&) override;
virtual void external_pki_sign_request(ExternalPKISignRequest&) override;
private:
// openvpn::ProfileMerge *profileMerge;
// Config *config;
}
#endif
Also if I remove the #include <openvpn/options/merge.hpp>
the reference to overloaded function ...to call it? OPENVPN_LOG_NTNL(...
goes away and I'm back with duplicate symbols. Why is it that I have to include a cpp file (why isn't it ovpncli.hpp) that should be included ? I'm confused here, as the cpp inclusion seems to be the reason for duplicated symbols. I have a typical Qt App:
main.cpp -> includes mainwindow.h
mainwindow.cpp
mainwindow.h -> includes client.h
client.cpp
client.h -> include ovpncli.cpp
And symbols are duplicated in main.o
and client.o
Is there anything I can do ? The problem once again seems to be that I have to include the .cpp file instead of an .hpp file. But that causes the duplicate symbols error.
Please have a close look at how the reference client (test/ovpncli/cli.cpp) does things. Another reference point is the openvpn3-linux implementation (openvpn3-service-client, core-client.hpp). These two implementations manages to implement the client without any duplicated symbols.
It is hard to understand what is going wrong without seeing the whole picture as well, so without sharing your project with us, we will just be shooting blindly in the dark.
I already looked the cli.cpp before, I've tried having same includes/defines, but same result. I took a quick look at core-client.cpp but it seems they also include the ovpncli.cpp (which seems to be the root cause).
It seems odd to have to include a .cpp file for a library instead of .hpp...
Here is the full compilation log which ends up giving me duplicated symbols: https://pastebin.com/1aLNstpL
We need the full source code of your implementation too. Plus it would help a lot if all the warnings and errors weren't in French. We are also chasing a ghost here, as the earlier compiler warnings you showed here seems to be from a Mac running XCode, while this pastebin seems to be from a Windows box - which means: Quite different compiler environments.
In regards to the .cpp file inclusion. A file name is a file name, which is the argument given to #include, regardless of the extension. There is nothing special about including a .cpp except of it being a bit unusual. But it needs to be like this for other use cases this library has.
I believe the root cause is wrong order of #include statements. And then you build several object files from .cpp files, where some of the same symbols ends up being in more object files, which then explodes when these objects files are getting linked together. You need to figure out a way to untangle this, as it won't compile as it is now.
But since you're playing with Qt, also ensure that you use at least -std=c++11, preferably -std=c++14. Depending on Qt versions, this might or might not work - I don't know how compliant your Qt targets are with those standards.
I'm closing this now, as this seems to be more a local implementation issue and not a bug in the OpenVPN 3 Core library.
I get "404 This is not the web page you are looking for." on both these URLs.
Oh, wait ... the URLs are wrong, the "text version" of the URL works.
Ok sorry the link is fixed
You have #include <openvpn/io/io.hpp>
on line 6 in client.h
. Try moving that one below line 11. But if you have more files including client.h which are built as separate object files, you will still most likely hit the duplicated symbols error. This needs to be resolved differently as well.
I also see you have: #define OPENVPN_CORE_API_VISIBILITY_HIDEN
. There's a typo here. It should say HIDDEN
not HIDEN
.
I've moved the io.hpp
include below ovpncli.hpp
, and fixed the typo. As for client.h
it is included by mainwindow.h
which in turn is included by main.cpp
(mainwindow.h
seems to also be included by moc_mainwindow.h
), what do you mean it should be "resolved differently" ?
Generally OpenVPN3 core is a bit different than most libraries. The whole implementation is header only.
To fix the problem you are seeing I would if possible for you include the openvpn header in only one c/c++ file and make only that file access openvpn3 directly and the rest of your program go that that class/file with function calls. We might fix openvpn3 in the future to be used more like a normal c++ library but at the moment that is the approach you need to take.
@schwave So the idea is to include the ovpncli.hpp (instead of ovpncli.cpp) only in one class (that's what I'm doing at the moment) ? Because I have tried that and I get different errors
No, you must use ovpncli.cpp
.
So I have a client.h
class which include the ovpncli.cpp
and makes the implementation. Then mainwindow.cpp
uses Client
class and not OpenVPNClient
class directly, but that's where I was before and had the duplicated symbols, so I'm confused regarding your last message.
Your duplicated symbols issues is tied to
duplicate symbol __ZN7openvpn9ClientAPI13OpenVPNClient16crypto_self_testEv in:
main.o
mainwindow.o
So both main.cpp and mainwindow.cpp is including the same openvpn3 header file somewhere in the chain. This needs to be decoupled, so that only one of these source files includes ovpncli.cpp
.
Or how I understand what @schwabe says, you have your own implementation of the "OpenVPN 3 Client class" where the declaration is exported in a .hpp file, used by both main.cpp and mainwindow.cpp and the implementation is built separately from its own .cpp file. When linking this together, you will only have the needed symbols defined in a single object file.
And just to clarify an ugly detail in the last paragraph ... the declaration cannot include any openvpn3 header files, those needs to be included in the implementation file only.
So if my client.h (Client class) is the one I expose, It should not include any openvpn3 headers files (but rather the client.cpp should include those) right ? I have tried that, and symbols are duplicated still.... I'm sorry but I really don't understand how I should go about this.
I have a my client.h
class (inheriting OpenVPNClient) decalaration, the implementation is inside client.cpp
(I have tried including openvpn3 headers here too instead of in the client.h
), then my mainwindow.h
includes the client.h
and main.cpp
includes mainwindow.h
You might need to ensure that you do not expose any OpenVPN 3 related symbols at all in client.h
.
As I see the current include chain in your current github repository (git master commit eb0c800fb77ce5c889b78daf74219c4ece14b1fa):
* mainwindow.cpp includes:
- mainwindow.h includes:
- client.hpp includes
- ovpncli.cpp
* main.cpp includes
- mainwindow.h includes
- client.hpp includes:
- ovpncli.cpp
Here you see that ovpncli.cpp
gets included twice, via separate .cpp
files - which is compiled separately into separate object files, both containing the same symbols from ovpncli.cpp
. This is why client.hpp cannot include any openvpn3 source files, otherwise you will have duplicated symbols conflict, all pointing at ovpncli.cpp
.
So you need to be sure that your client.h
is completely openvpn3 agnostic, only exports its own declarations. And the client.cpp
which includes ovpncli.cpp
with the needed implementation. This needs to built separately (into it's own client.o
object file) and then this object file can be linked together with mainwindow.o
and main.o
and the end result is your executable client.
I understand now, I've got it working.
Thank you very much for the help 👍
Hello,
I'm trying to use this library to create an simple openvpn client, however I don't really know how to include it properly into my c++ application.
I have tried with following includepath : -Iopenvpn3/
With above I get a bunch of "Redefinition of X" (ServerEntry, etc...)
So I'm not sure how this library should be used. Should I use the classes inside openvpn3/openvpn/ only ? From what I understand in readme, I should be using the OpenVPNClient interface inside openvpn3/client/
Thanks in advance.