1 编译安装libhv

编译libhv需要:

  • gcc4.8+
  • cmake 3.6 or later

官方编译文档可参考:https://github.com/ithewei/libhv/blob/master/BUILD.md

官方提供了两种编译方式,一种是Makefile,另一种是CMake,本文以CMake为例进行说明。

2 CMake编译libhv

首先下载libhv,这里以libhv v1.3.2为例

wget -c https://github.com/ithewei/libhv/archive/refs/tags/v1.3.2.tar.gz

解压缩

tar -xvf v1.3.2.tar.gz

进入到解压缩目录

cd libhv-1.3.2

创建build文件夹,进入build文件夹

mkdir build
cd build

然后通过cmake进行编译

cmake ..
cmake --build .

或者

cmake ..
make

cmake提供了比较多的编译选项,具体可参考官方CMakeLists,主要的编译选项如下

option(BUILD_SHARED "build shared library" ON)
option(BUILD_STATIC "build static library" ON)

option(BUILD_EXAMPLES "build examples" ON)
option(BUILD_UNITTEST "build unittest" OFF)

# see config.ini
option(WITH_PROTOCOL "compile protocol" OFF)

option(WITH_EVPP "compile evpp" ON)
option(WITH_HTTP "compile http" ON)
option(WITH_HTTP_SERVER "compile http/server" ON)
option(WITH_HTTP_CLIENT "compile http/client" ON)
option(WITH_MQTT "compile mqtt" OFF)

option(ENABLE_UDS "Unix Domain Socket" OFF)
option(USE_MULTIMAP "MultiMap" OFF)

option(WITH_CURL "with curl library (deprecated)" OFF)
option(WITH_NGHTTP2 "with nghttp2 library" OFF)

option(WITH_OPENSSL "with openssl library" OFF)
option(WITH_GNUTLS  "with gnutls library"  OFF)
option(WITH_MBEDTLS "with mbedtls library" OFF)

option(WITH_KCP "compile event/kcp" OFF)

在通过cmake ..默认编译的情况下会同时编译动态库和静态库,编译完成之后:

  • include目录位于build/include目录下
  • 动态库和静态库位于build/lib目录下

然后使用

make install

进行安装,安装之后的路径为

  • include目录:/usr/local/include
  • 静态库目录:/usr/local/lib
  • 动态库目录:/usr/local/lib

安装完成之后,使用以下命令

sudo ldconfig

使得动态链接库配置生效,就可以在自己的项目中动态链接libhv库了。

详细的安装日志为

Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libhv.so
-- Set runtime path of "/usr/local/lib/libhv.so" to ""
-- Installing: /usr/local/lib/libhv_static.a
-- Installing: /usr/local/include/hv/hv.h
-- Installing: /usr/local/include/hv/hconfig.h
-- Installing: /usr/local/include/hv/hexport.h
-- Installing: /usr/local/include/hv/hplatform.h
-- Installing: /usr/local/include/hv/hdef.h
-- Installing: /usr/local/include/hv/hatomic.h
-- Installing: /usr/local/include/hv/herr.h
-- Installing: /usr/local/include/hv/htime.h
-- Installing: /usr/local/include/hv/hmath.h
-- Installing: /usr/local/include/hv/hbase.h
-- Installing: /usr/local/include/hv/hversion.h
-- Installing: /usr/local/include/hv/hsysinfo.h
-- Installing: /usr/local/include/hv/hproc.h
-- Installing: /usr/local/include/hv/hthread.h
-- Installing: /usr/local/include/hv/hmutex.h
-- Installing: /usr/local/include/hv/hsocket.h
-- Installing: /usr/local/include/hv/hlog.h
-- Installing: /usr/local/include/hv/hbuf.h
-- Installing: /usr/local/include/hv/hmain.h
-- Installing: /usr/local/include/hv/hendian.h
-- Installing: /usr/local/include/hv/hssl.h
-- Installing: /usr/local/include/hv/hloop.h
-- Installing: /usr/local/include/hv/nlog.h
-- Installing: /usr/local/include/hv/base64.h
-- Installing: /usr/local/include/hv/md5.h
-- Installing: /usr/local/include/hv/sha1.h
-- Installing: /usr/local/include/hv/hmap.h
-- Installing: /usr/local/include/hv/hstring.h
-- Installing: /usr/local/include/hv/hfile.h
-- Installing: /usr/local/include/hv/hpath.h
-- Installing: /usr/local/include/hv/hdir.h
-- Installing: /usr/local/include/hv/hurl.h
-- Installing: /usr/local/include/hv/hscope.h
-- Installing: /usr/local/include/hv/hthreadpool.h
-- Installing: /usr/local/include/hv/hasync.h
-- Installing: /usr/local/include/hv/hobjectpool.h
-- Installing: /usr/local/include/hv/ifconfig.h
-- Installing: /usr/local/include/hv/iniparser.h
-- Installing: /usr/local/include/hv/json.hpp
-- Installing: /usr/local/include/hv/singleton.h
-- Installing: /usr/local/include/hv/ThreadLocalStorage.h
-- Installing: /usr/local/include/hv/Buffer.h
-- Installing: /usr/local/include/hv/Channel.h
-- Installing: /usr/local/include/hv/Event.h
-- Installing: /usr/local/include/hv/EventLoop.h
-- Installing: /usr/local/include/hv/EventLoopThread.h
-- Installing: /usr/local/include/hv/EventLoopThreadPool.h
-- Installing: /usr/local/include/hv/Status.h
-- Installing: /usr/local/include/hv/TcpClient.h
-- Installing: /usr/local/include/hv/TcpServer.h
-- Installing: /usr/local/include/hv/UdpClient.h
-- Installing: /usr/local/include/hv/UdpServer.h
-- Installing: /usr/local/include/hv/httpdef.h
-- Installing: /usr/local/include/hv/wsdef.h
-- Installing: /usr/local/include/hv/http_content.h
-- Installing: /usr/local/include/hv/HttpMessage.h
-- Installing: /usr/local/include/hv/HttpParser.h
-- Installing: /usr/local/include/hv/WebSocketParser.h
-- Installing: /usr/local/include/hv/WebSocketChannel.h
-- Installing: /usr/local/include/hv/HttpServer.h
-- Installing: /usr/local/include/hv/HttpService.h
-- Installing: /usr/local/include/hv/HttpContext.h
-- Installing: /usr/local/include/hv/HttpResponseWriter.h
-- Installing: /usr/local/include/hv/WebSocketServer.h
-- Installing: /usr/local/include/hv/HttpClient.h
-- Installing: /usr/local/include/hv/requests.h
-- Installing: /usr/local/include/hv/axios.h
-- Installing: /usr/local/include/hv/AsyncHttpClient.h
-- Installing: /usr/local/include/hv/WebSocketClient.h
-- Installing: /usr/local/lib/cmake/libhv/libhvConfig.cmake
-- Installing: /usr/local/lib/cmake/libhv/libhvConfig-noconfig.cmake

3 自定义demo cmake编译示例

新建一个main.cpp,在其中加入以下代码

#include <iostream>
#include "hv/HttpServer.h"

int main() {
    HttpService router;
    router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
        return resp->String("pong");
        });

    router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
        static char data[] = "0123456789";
        return resp->Data(data, 10);
        });

    router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
        return resp->Json(router.Paths());
        });

    router.GET("/get", [](HttpRequest* req, HttpResponse* resp) {
        resp->json["origin"] = req->client_addr.ip;
        resp->json["url"] = req->url;
        resp->json["args"] = req->query_params;
        resp->json["headers"] = req->headers;
        return 200;
        });

    router.POST("/echo", [](const HttpContextPtr& ctx) {
        return ctx->send(ctx->body(), ctx->type());
        });

    http_server_t server;
    server.port = 8080;
    server.service = &router;
    std::cout << "run success" << std::endl;
    http_server_run(&server);
    return 0;
}

然后在同级目录下创建一个CMakeLists.txt

如果是静态链接libhv,则CMakeLists.txt的内容为

cmake_minimum_required(VERSION 3.6)

project(myhvtest)

set(CMAKE_BUILD_TYPE Release)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -pthread -fPIC -ldl")

# 添加宏定义
add_definitions(-DHV_STATICLIB)

# 链接静态库
link_libraries(libhv_static.a)

add_executable(${PROJECT_NAME} main.cpp)

如果是动态链接libhv,则CMakeLists.txt的内容为

cmake_minimum_required(VERSION 3.6)

project(myhvtest)

set(CMAKE_BUILD_TYPE Release)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -pthread -fPIC -ldl")

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} hv)

然后依次执行以下命令进行编译

mkdir build
cd build
cmake ..
make

编译成功之后会在build目录下生成一个myhvtest的可执行文件。

如何判断可执行程序是否动态链接libhv成功?

使用以下命令

ldd ./myhvtest

如果出现以下日志则说明链接成功

[root@ai-0008 build]# ldd ./myhvtest
        linux-vdso.so.1 =>  (0x00007ffe9f138000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f1765ab3000)
        libhv.so => /usr/local/lib/libhv.so (0x00007f176585c000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f1765554000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f1765252000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f176503c000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1764e20000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f1764a52000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1765cb7000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f176484a000)

参考