如何在简单的 C++ 项目中使用 Poco 库?
How to use Poco library in a simple C++ project?
这是我项目的目录结构:
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 中的一个错误引起的
那么我该如何解决这个问题?
第 target_link_libraries(main ${POCO_LIBRARIES})
行无法正常工作。该变量仅在查找模块中定义。它甚至可能不适用于现代软件包。
如果你想使用poco作为项目子目录,那么我建议link他们的目标:
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
我也有类似的问题。我确实构建了以下测试用例。它基于 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();
}
您也可以使用 cmake
标志代替 CMakeLists.txt
中的 set(CMAKE_PREFIX_PATH ...)
。如果您想使用不同的 Poco 实例,这会使它更加灵活。
例如,如果你 'installed' 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'
这是我项目的目录结构:
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 中的一个错误引起的
那么我该如何解决这个问题?
第 target_link_libraries(main ${POCO_LIBRARIES})
行无法正常工作。该变量仅在查找模块中定义。它甚至可能不适用于现代软件包。
如果你想使用poco作为项目子目录,那么我建议link他们的目标:
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
我也有类似的问题。我确实构建了以下测试用例。它基于 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();
}
您也可以使用 cmake
标志代替 CMakeLists.txt
中的 set(CMAKE_PREFIX_PATH ...)
。如果您想使用不同的 Poco 实例,这会使它更加灵活。
例如,如果你 'installed' 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'