Search code examples
c++cmakepoco-libraries

How to use Poco library in a simple C++ project?


This is my project's directory structure:

poco/
CMakeLists.txt
main.cpp

note: poco directory contains all the file downloaded from Poco's github repository by using this command:

git clone --recurse-submodules https://github.com/pocoproject/poco.git

This is the content of the CMakeLists.txt:

cmake_minimum_required(VERSION 3.4.1)
add_executable(
    main
    main.cpp
)
add_subdirectory(poco)
include_directories(
   poco/ApacheConnector/include
   poco/CppParser/include
   poco/CppUnit/include
   poco/Crypto/include
   poco/Data/include
   poco/Encodings/include
   poco/Foundation/include
   poco/JSON/include
   poco/MongoDB/include
   poco/Net/include
   poco/NetSSL_OpenSSL/include
   poco/NetSSL_Win/include
   poco/openssl/build/include
   poco/PDF/include
   poco/Redis/include
   poco/SevenZip/include
   poco/Util/include
   poco/XML/include
   poco/Zip/include
)

target_link_libraries(main ${POCO_LIBRARIES})

And this is the content of the main.cpp:

#include <iostream>
#include <Poco/Net/HTTPClientSession.h>
using namespace std;
int main() {
    std::cout << "here";

    return 0;
}

After I run these commands(in the directory whose structure was presented):

$mkdir _build && cd _build
$cmake ..
$make

I encounter these errors:

[  0%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[  1%] Linking CXX executable main
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv6SocketAddressImpl::host() const':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:143: undefined reference to `Poco::Net::IPAddress::IPAddress(void const*, unsigned int, unsigned int)'
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv6SocketAddressImpl::~IPv6SocketAddressImpl()':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:118: undefined reference to `Poco::Net::Impl::SocketAddressImpl::~SocketAddressImpl()'
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv6SocketAddressImpl::~IPv6SocketAddressImpl()':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:118: undefined reference to `Poco::Net::Impl::SocketAddressImpl::~SocketAddressImpl()'
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv4SocketAddressImpl::~IPv4SocketAddressImpl()':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:56: undefined reference to `Poco::Net::Impl::SocketAddressImpl::~SocketAddressImpl()'
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv4SocketAddressImpl::~IPv4SocketAddressImpl()':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:56: undefined reference to `Poco::Net::Impl::SocketAddressImpl::~SocketAddressImpl()'
CMakeFiles/main.dir/main.cpp.o: In function `Poco::Net::Impl::IPv4SocketAddressImpl::host() const':
/home/gandalf/Desktop/pocoTest/poco/Net/include/Poco/Net/SocketAddressImpl.h:81: undefined reference to `Poco::Net::IPAddress::IPAddress(void const*, unsigned int)'
CMakeFiles/main.dir/main.cpp.o:(.data.rel.ro._ZTIN4Poco3Net4Impl21IPv4SocketAddressImplE[_ZTIN4Poco3Net4Impl21IPv4SocketAddressImplE]+0x10): undefined reference to `typeinfo for Poco::Net::Impl::SocketAddressImpl'
CMakeFiles/main.dir/main.cpp.o:(.data.rel.ro._ZTIN4Poco3Net4Impl21IPv6SocketAddressImplE[_ZTIN4Poco3Net4Impl21IPv6SocketAddressImplE]+0x10): undefined reference to `typeinfo for Poco::Net::Impl::SocketAddressImpl'
CMakeFiles/main.dir/main.cpp.o:(.data.rel.ro._ZTVN4Poco3Net4Impl21IPv4SocketAddressImplE[_ZTVN4Poco3Net4Impl21IPv4SocketAddressImplE]+0x50): undefined reference to `Poco::Net::Impl::IPv4SocketAddressImpl::toString[abi:cxx11]() const'
CMakeFiles/main.dir/main.cpp.o:(.data.rel.ro._ZTVN4Poco3Net4Impl21IPv6SocketAddressImplE[_ZTVN4Poco3Net4Impl21IPv6SocketAddressImplE]+0x50): undefined reference to `Poco::Net::Impl::IPv6SocketAddressImpl::toString[abi:cxx11]() const'
collect2: error: ld returned 1 exit status
CMakeFiles/main.dir/build.make:94: recipe for target 'main' failed
make[2]: *** [main] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed
make[1]: *** [CMakeFiles/main.dir/all] Error 2
Makefile:151: recipe for target 'all' failed
make: *** [all] Error 2

From what I have figured out, Poco::Net::IPAddress::IPAddress must be Poco::Net::IPAddress. And I don't know why the linker adds an extra IPAddress to Poco::Net::IPAddress. And this problem seems to arise from an error in CMakeLists.txt So how can I fix this?


Solution

  • The line target_link_libraries(main ${POCO_LIBRARIES}) won't work as intended. That variable is only defined in find modules. It may not even work with modern packages.

    If you want to use poco as a project subdirectory, then I suggest to link to their targets:

    cmake_minimum_required(VERSION 3.4.1)
    
    add_executable(
        main
        main.cpp
    )
    
    add_subdirectory(poco)
    target_link_libraries(main PUBLIC PocoNet ...) # replace `...` by all poco library you use