【问题标题】:How to use Poco library in a simple C++ project?如何在简单的 C++ 项目中使用 Poco 库?
【发布时间】:2019-10-28 13:55:55
【问题描述】:

这是我项目的目录结构:

poco/
CMakeLists.txt
main.cpp

注意:poco 目录包含使用此命令从 Poco 的 github 存储库下载的所有文件:

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

这是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})

这是main.cpp的内容:

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

    return 0;
}

在我运行这些命令后(在其结构出现的目录中):

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

我遇到了这些错误:

[  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

据我所知,Poco::Net::IPAddress::IPAddress 必须是Poco::Net::IPAddress。而且我不知道为什么链接器会在Poco::Net::IPAddress 中添加额外的IPAddress。 而这个问题似乎是由 CMakeLists.txt 中的错误引起的 那么我该如何解决呢?

【问题讨论】:

  • POCO_LIBRARIES 未设置,因此您没有链接到库。
  • @JohnZwinck 我应该怎么做?
  • 链接器添加了另一个IPAddress,因为它引用了该类的构造函数。只是想知道:难道你不能找到提供 Poco 的软件包,这样你就不需要手动安装它们了吗?
  • 我试过 find_package 但我得到了这个错误:
  • 由于没有在 CMAKE_MODULE_PATH 中提供“FindPoco.cmake”,该项目要求 CMake 查找“Poco”提供的包配置文件

标签: c++ cmake poco-libraries


【解决方案1】:

target_link_libraries(main ${POCO_LIBRARIES}) 行无法按预期工作。该变量仅在查找模块中定义。它甚至可能不适用于现代软件包。

如果你想使用 poco 作为项目子目录,那么我建议链接到他们的目标:

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

【讨论】:

  • 我试过这个,但在 _build 目录中运行 make 命令时出现以下错误:main.cpp:2:10: 致命错误:Poco/Net/HTTPClientSession.h: No such file or directory #include
  • @gandalf 尝试改用PocoNet
  • 对不起,我忘了添加这一行 add_subdirectory(poco)
  • @gandalf 没有名为 PUBLIC 的 poco 库。 all caps 参数是 CMake 中依赖项的可见性。应该是:target_link_libraries(your_target &lt;PUBLIC|PRIVATE|INTERFACE&gt; all_your_dependencies_here)
  • @NguyễnĐứcTâm 不,只有可执行文件的名称。每个项目可以有许多可执行文件和库。
【解决方案2】:

我也有类似的问题。我确实构建了以下测试用例。它基于 Linux 系统(opensuse)。这个例子并不完美——不能保证。

bash 命令:

$ git clone --depth=1 --branch=master --recurse-submodules https://github.com/pocoproject/poco.git
$ cd poco && mkdir poco-build && cd poco-build
$ cmake -H .. -B . -DCMAKE_INSTALL_PREFIX=~/libs
$ cmake --build . --target install

bash 例程将编译 poco 库并在 ~/libs 本地安装所需的 headers/libraries/cmake/... 文件。这当然可以改变。


使用以下文件。

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

project(PocoTimer)
set(CMAKE_PREFIX_PATH /home/<user>/libs/poco/lib/cmake/Poco)

find_package(Poco REQUIRED Foundation)

add_executable(
    main main.cpp
)

target_link_libraries(
    main
    PRIVATE Poco::Foundation
)

main.cpp

#include "Poco/Timer.h"
#include "Poco/Thread.h"
#include "Poco/Stopwatch.h"
#include <iostream>

/*
 * Main application 
 */

class PocoTimer
{
public:
    //------------
    PocoTimer() { stopWatch.start(); }
    //------------
    void PrintElapsedTime(Poco::Timer& timer)
    {
      std::cout << "Time elapsed: " << stopWatch.elapsed() / 1000 << " milliseconds." << std::endl;
    }
private:
    Poco::Stopwatch stopWatch;
};


int main() {

PocoTimer pocoTimer;
Poco::Timer timer(250, 500);
// -- print command -- //
timer.start(Poco::TimerCallback<PocoTimer>(pocoTimer, &PocoTimer::PrintElapsedTime));
Poco::Thread::sleep(5000);
timer.stop();

}

您可以在CMakeLists.txt 中使用cmake 标志而不是set(CMAKE_PREFIX_PATH ...)。如果您想使用不同的 Poco 实例,这将使其更加灵活。

例如,如果您将 Poco“安装”到 ~/libs

$ cmake -H. -B./build \
      -DPoco_DIR='/home/<user>/libs/poco/lib/cmake/Poco'

$ cmake -H. -B./build \
      -DCMAKE_PREFIX_PATH='/home/<user>/libs/poco/lib/cmake/Poco'

$ cmake -H. -B./build \
      -DCMAKE_MODULE_PATH='/home/<user>/libs/poco/lib/cmake/Poco'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2012-06-08
    • 2021-12-04
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    相关资源
    最近更新 更多