赞
踩
created: 2020-11-05 11:39:27
2010年上大二,我认定了C++,于是一直专攻C++。第一份工作也如愿找到了windows环境下的C++开发,然而只做了一年,后续由于工作变动,一直在用python/ruby/javascript,偶尔也会用下QT,纯正的C++被尘封了很多年,导致我的这把利器有些生锈。于是,近期打算把它捡起来好好磨磨。机缘巧合之下,了解到搜狗开源的C++服务器引擎sogou/workflow,轻盈优雅,且支撑后端几乎所有的C++在线业务,每日处理请求百亿次,一下子就打动我了,非常喜欢,打算花几个月时间啃透,学习一下优秀团队的编程思想、设计思路。
由于sogou/workflow项目官方没有出相应的安装配置说明,我自己摸索了很久才跑通第一个用例。在我做笔记的时候,我意识到,这个问题会过滤掉很多刚入行不久的伙伴,因为通常学习使用一个项目,第一步就是把它跑起来。那么,我就做个引路人,介绍一下环境如何配置,让用例跑起来,供大家参考。
https://github.com/sogou/workflow.git
https://zhuanlan.zhihu.com/p/165638263
https://www.oschina.net/p/sogou-cpp-workflow
注:以上两个环境均可正常运行。
# git clone https://github.com/sogou/workflow.git
或
# mkdir ~/workflow
# git clone --recursive https://github.com/sogou/workflow.git ~/workflow
# wget -P ~/Downloads -c https://cmake.org/files/v3.12/cmake-3.12.1.tar.gz
注意,不建议直接下载cmake-3.12.1-Linux-x86_64.tar.gz,这个是已经编译好的版本。
使用cmake-3.12.1.tar.gz比较好,下载后再make编译,这样安装后与本机的兼容性更好。
# mkdir ~/cmake3
# tar -zxvf cmake-3.12.1.tar.gz -C ~/cmake3
# cd ~/cmake3/cmake3-3.12.1
# ./configure
# make && make install
当前目录下将生成bin/目录,里面是可执行程序。
当然,如果你想节省时间,用编译后的也不失为一个方法。(文件大概33M)
# wget -P ~/Downloads -c https://cmake.org/files/v3.12/cmake-3.12.1-Linux-x86_64.tar.gz
# tar -zxvf cmake-3.12.1-Linux-x86_64.tar.gz -C ~/cmake3
# export PATH="$PATH:$HOME/cmake3/cmake3-3.12.1/bin"
# echo $PATH
/root/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/cmake3/cmake-3.12.1/bin
# cmake --version
cmake version 3.12.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
# cd ~/workflow # ./configure ./configure: line 2: cmake3: command not found CMAKE_C_FLAGS_DEBUG is -g CMAKE_C_FLAGS_RELEASE is -O3 -DNDEBUG CMAKE_C_FLAGS_RELWITHDEBINFO is -O2 -g -DNDEBUG CMAKE_C_FLAGS_MINSIZEREL is -Os -DNDEBUG CMAKE_CXX_FLAGS_DEBUG is CMAKE_CXX_FLAGS_RELEASE is CMAKE_CXX_FLAGS_RELWITHDEBINFO is CMAKE_CXX_FLAGS_MINSIZEREL is -- Configuring done -- Generating done -- Build files have been written to: /root/workflow # make
生成_include和_lib两个目录,前者是头文件,后者是静态库和动态库
# cd ~/opensource/workflow
# clang++ -std=c++11 -Wall tutorial/tutorial-01-wget.cc -I _include/ _L _lib/ -lworkflow -lssl -lcrypto -lpthread -o twget
# ./twget www.sougou.com
遇坑过程
# clang++ tutorial/tutorial-01-wget.cc -o twget
报错:
clang++ tutorial/tutorial-01-wget.cc
tutorial/tutorial-01-wget.cc:25:10: fatal error: 'workflow/HttpMessage.h' file not found
#include "workflow/HttpMessage.h"
^
1 error generated.
clang++ -std=c++11 -Wall tutorial/tutorial-01-wget.cc -I _include/ -o twget 报错: /data/tmp/tutorial-01-wget-f47913.o: In function `wget_callback(WFNetworkTask<protocol::HttpRequest, protocol::HttpResponse>*)': tutorial/tutorial-01-wget.cc:(.text+0x29c): undefined reference to `protocol::HttpHeaderCursor::next(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)' tutorial/tutorial-01-wget.cc:(.text+0x428): undefined reference to `protocol::HttpHeaderCursor::next(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)' /data/tmp/tutorial-01-wget-f47913.o: In function `main': tutorial/tutorial-01-wget.cc:(.text+0x79e): undefined reference to `WFTaskFactory::create_http_task(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, std::function<void (WFNetworkTask<protocol::HttpRequest, protocol::HttpResponse>*)>)' /data/tmp/tutorial-01-wget-f47913.o: In function `protocol::RedisValue::~RedisValue()': tutorial/tutorial-01-wget.cc:(.text._ZN8protocol10RedisValueD2Ev[_ZN8protocol10RedisValueD2Ev]+0x14): undefined reference to `protocol::RedisValue::free_data()' /data/tmp/tutorial-01-wget-f47913.o: In function `EncodeStream::~EncodeStream()': tutorial/tutorial-01-wget.cc:(.text._ZN12EncodeStreamD2Ev[_ZN12EncodeStreamD2Ev]+0xd): undefined reference to `EncodeStream::clear_buffer()' /data/tmp/tutorial-01-wget-f47913.o: In function `protocol::RedisMessage::~RedisMessage()': tutorial/tutorial-01-wget.cc:(.text._ZN8protocol12RedisMessageD2Ev[_ZN8protocol12RedisMessageD2Ev]+0x27): undefined reference to `redis_parser_deinit' /data/tmp/tutorial-01-wget-f47913.o: In function `protocol::HttpMessage::get_parsed_body(void const**, unsigned long*) const': tutorial/tutorial-01-wget.cc:(.text._ZNK8protocol11HttpMessage15get_parsed_bodyEPPKvPm[_ZNK8protocol11HttpMessage15get_parsed_bodyEPPKvPm]+0x25): undefined reference to `http_parser_get_body' /data/tmp/tutorial-01-wget-f47913.o: In function `protocol::HttpMessage::add_header_pair(char const*, char const*)': tutorial/tutorial-01-wget.cc:(.text._ZN8protocol11HttpMessage15add_header_pairEPKcS2_[_ZN8protocol11HttpMessage15add_header_pairEPKcS2_]+0x5d): undefined reference to `http_parser_add_header' /data/tmp/tutorial-01-wget-f47913.o: In function `WFCounterTask::done()': tutorial/tutorial-01-wget.cc:(.text._ZN13WFCounterTask4doneEv[_ZN13WFCounterTask4doneEv]+0x74): undefined reference to `SeriesWork::pop()' /data/tmp/tutorial-01-wget-f47913.o: In function `WFCounterTask::count()': tutorial/tutorial-01-wget.cc:(.text._ZN13WFCounterTask5countEv[_ZN13WFCounterTask5countEv]+0x3b): undefined reference to `SubTask::subtask_done()' /data/tmp/tutorial-01-wget-f47913.o: In function `WFGenericTask::dispatch()': tutorial/tutorial-01-wget.cc:(.text._ZN13WFGenericTask8dispatchEv[_ZN13WFGenericTask8dispatchEv]+0x18): undefined reference to `SubTask::subtask_done()' /data/tmp/tutorial-01-wget-f47913.o: In function `WFGenericTask::done()': tutorial/tutorial-01-wget.cc:(.text._ZN13WFGenericTask4doneEv[_ZN13WFGenericTask4doneEv]+0x43): undefined reference to `SeriesWork::pop()' /data/tmp/tutorial-01-wget-f47913.o: In function `Workflow::start_series_work(SubTask*, std::function<void (SeriesWork const*)>)': tutorial/tutorial-01-wget.cc:(.text._ZN8Workflow17start_series_workEP7SubTaskSt8functionIFvPK10SeriesWorkEE[_ZN8Workflow17start_series_workEP7SubTaskSt8functionIFvPK10SeriesWorkEE]+0x47): undefined reference to `SeriesWork::SeriesWork(SubTask*, std::function<void (SeriesWork const*)>&&)' /data/tmp/tutorial-01-wget-f47913.o: In function `WFFuture<void>::wait() const': tutorial/tutorial-01-wget.cc:(.text._ZNK8WFFutureIvE4waitEv[_ZNK8WFFutureIvE4waitEv]+0x49): undefined reference to `WFGlobal::get_scheduler()' tutorial/tutorial-01-wget.cc:(.text._ZNK8WFFutureIvE4waitEv[_ZNK8WFFutureIvE4waitEv]+0x6c): undefined reference to `WFGlobal::sync_operation_begin()' tutorial/tutorial-01-wget.cc:(.text._ZNK8WFFutureIvE4waitEv[_ZNK8WFFutureIvE4waitEv]+0x87): undefined reference to `WFGlobal::sync_operation_end()' /data/tmp/tutorial-01-wget-f47913.o: In function `CommScheduler::is_handler_thread()': tutorial/tutorial-01-wget.cc:(.text._ZN13CommScheduler17is_handler_threadEv[_ZN13CommScheduler17is_handler_threadEv]+0x15): undefined reference to `Communicator::is_handler_thread()' /data/tmp/tutorial-01-wget-f47913.o:(.rodata._ZTVN8protocol12RedisMessageE[_ZTVN8protocol12RedisMessageE]+0x10): undefined reference to `protocol::RedisMessage::encode(iovec*, int)' /data/tmp/tutorial-01-wget-f47913.o:(.rodata._ZTVN8protocol12RedisMessageE[_ZTVN8protocol12RedisMessageE]+0x28): undefined reference to `protocol::RedisMessage::append(void const*, unsigned long*)' /data/tmp/tutorial-01-wget-f47913.o:(.rodata._ZTVN8protocol12RedisMessageE[_ZTVN8protocol12RedisMessageE]+0x48): undefined reference to `non-virtual thunk to protocol::RedisMessage::append(void const*, unsigned long*)' clang: error: linker command failed with exit code 1 (use -v to see invocation)
最终:
# clang++ -std=c++11 -Wall tutorial/tutorial-01-wget.cc -I _include/ -L _lib/ -lworkflow -o twget
或
# clang++ -std=c++11 -Wall tutorial/tutorial-01-wget.cc -I _include/ -L _lib -lworkflow -lssl -lcrypto -lpthread -o twget
OK,成功编译
然而,有更简单的办法。。。
官方提供了CMake,直接到tutorial/目录下执行make即可生成所有用例的可执行程序。
# ./twget sogou.com
打印出html内容。
好了,可以开始我们的学习之旅啦。如果帮到你了,请点个赞或者评论一下,让更多人的知道,少走弯路。
(全文完)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。