Browse Source

#4 Linux适配

Signed-off-by: wlxuz <myxuan475@126.com>
Change-Id: Ide90accb325a7fccb0ace6c7d39a528eca7af874
wlxuz 10 months ago
parent
commit
013ddf3849
5 changed files with 378 additions and 0 deletions
  1. 54 0
      Linux/CMakeLists.txt
  2. 50 0
      Linux/vendor.json
  3. 22 0
      Linux/vendor_global.h
  4. 181 0
      vendor_base.cpp
  5. 71 0
      vendor_base.h

+ 54 - 0
Linux/CMakeLists.txt

@@ -0,0 +1,54 @@
+
+#rights reserved
+cmake_minimum_required(VERSION 3.6)
+
+include("${ROOT_DIR}/buildtools/cmake/toolchain_common.cmake")
+#project name
+set(PROJECT_NAME "leo-das")
+
+message(INFO " SYSTEM_ARCH:${SYSTEM_ARCH}\n")
+set(CMAKE_BUILD_TYPE DEBUG)
+set(CMAKE_CXX_FLAGS "-fPIC -std=gnu++11 -Wno-error=implicit-function-declaration -Wno-error=int-conversion")
+set(CMAKE_C_FLAGS "-O3 -fPIC -Wunused-result -Wno-error=implicit-function-declaration -Wno-error=int-conversion")
+
+# 获取当前的分支
+set(GIT_BRANCH "")
+get_git_branch(GIT_BRANCH)
+string(REGEX REPLACE ".*/(.*)" "\\1" _git_branch "${GIT_BRANCH}")
+message(STATUS "Git branch is ${_git_branch}")                     # 宏的结束
+
+add_definitions(-DDAS_VERSION=\"${_git_branch}\")
+
+project(${PROJECT_NAME})
+
+message("PRODUCT_NAME: ${PRODUCT_NAME}")
+message(STATUS "PROJECT_SOURCE_DIR: ${PRODUCT_ROOT_DIR}, PROJECT_BINARY_DIR: ${PRODUCT_BUILD_DIR}")
+
+add_definitions(-DPRODUCT_NAME=\"${PRODUCT_NAME}\")
+add_definitions(-DUSE_HTNICE)
+add_definitions(-DHTNICE_K4)
+
+set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libs?" FORCE)
+
+include_directories(${PRODUCT_ROOT_DIR})
+include_directories(${PRODUCT_ROOT_DIR}/thirdparty)
+include_directories(${PRODUCT_ROOT_DIR}/vendor/${PRODUCT_NAME})
+include_directories(${PRODUCT_BUILD_DIR}/thirdparty)
+
+find_library(OPENSSL_SSL_LIBRARY ssl ${OPENSSL_ROOT_DIR}/ssl NO_DEFAULT_PATH)
+find_library(OPENSSL_CRYPTO_LIBRARY crypto ${OPENSSL_ROOT_DIR}/crypto/ NO_DEFAULT_PATH)
+set(OPENSSL_INCLUDE_DIR "${PRODUCT_BUILD_DIR}/thirdparty/openssl/include")
+
+message("OPENSSL: ${OPENSSL_ROOT_DIR}/ssl, OPENSSL_SSL_LIBRARY: ${OPENSSL_SSL_LIBRARY}, OPENSSL_CRYPTO_LIBRARY: ${OPENSSL_CRYPTO_LIBRARY}, OPENSSL_INCLUDE_DIR: ${OPENSSL_INCLUDE_DIR}")
+
+set(LIBXML2_WITH_PYTHON OFF)
+# build_subdirectory(thirdparty/libxml2 INCLUDE thirdparty/libxml2)
+
+# build_subdirectory(thirdparty/SQLiteCpp INCLUDE thirdparty/SQLiteCpp/sqlite3)
+include_directories(${PRODUCT_ROOT_DIR}/thirdparty/SQLiteCpp/sqlite3)
+
+build_subdirectory(utils)
+
+# build_subdirectory(foundation/gw_leo)
+
+build_subdirectory(foundation/webconfig)

+ 50 - 0
Linux/vendor.json

@@ -0,0 +1,50 @@
+{
+    "product-name": "Linux",
+    "version": "1.0.0",
+    "toolchain":"",
+    "build-mode": "Debug",
+    "modules":[
+        {
+            "name": "jsoncpp",
+            "options": [],
+            "include":"$PRODUCT_ROOT_DIR/thirdparty/jsoncpp/include"
+        },
+        {
+            "name": "openssl",
+            "exports" : ["OPENSSL_ROOT_DIR=$PRODUCT_BUILD_DIR/thirdparty/openssl"]
+        },
+        {
+            "name": "mbedtls"
+        },
+        {
+            "name": "zlib"
+        },
+        {
+            "name": "SQLiteCpp"
+        },
+        {
+            "name": "tinyxml2"
+        },
+        {
+            "name" : "goahead",
+            "include":"$PRODUCT_BUILD_DIR/thirdparty/goahead/build/linux-x64-default/inc",
+            "link": "$PRODUCT_BUILD_DIR/thirdparty/goahead/build/linux-x64-default/bin",
+            "install":[
+                {
+                    "files" : ["$PRODUCT_BUILD_DIR/thirdparty/goahead/build/linux-x64-default/*"],
+                    "dstdir": "linux-x64-default"
+                }
+            ],
+            "exports":[
+            ]
+        },
+        {
+            "name": "libevent",
+            "options":["-DEVENT__DISABLE_TESTS=ON", "-DEVENT__HAVE_EPOLL_PWAIT2=0"]
+        },
+        {
+            "name": "xfrpc",
+            "options":["-DTHIRDPARTY_STATIC_BUILD=ON"]
+        }
+    ]
+}

+ 22 - 0
Linux/vendor_global.h

@@ -0,0 +1,22 @@
+#ifndef __VENDOR_GLOBAL_H__
+#define __VENDOR_GLOBAL_H__
+#include <utils/logger.h>
+#include <utils/macro.h>
+
+#define VENDOR_MAX_PATH_SIZE 256
+#define VENDOR_RUN_PATH_ENV  "DAS_CONFIG_DIR"
+
+static inline std::string vendor_env_dir()
+{
+    ASSERT(getenv(VENDOR_RUN_PATH_ENV) != nullptr);
+    return std::string(getenv(VENDOR_RUN_PATH_ENV));
+}
+
+const std::string VENDOR_CONFIG_PATH = vendor_env_dir() + "/config";
+const std::string VENDOR_LOG_PATH = vendor_env_dir() + "/log";
+const std::string VENDOR_BIN_PATH = vendor_env_dir() + "/bin";
+const std::string VENDOR_DB_PATH = vendor_env_dir() + "/data";
+const std::string VENDOR_WWW_PATH = vendor_env_dir() + "/WWW";
+
+#include "vendor/vendor_base.h"
+#endif // __VENDOR_GLOBAL_H__

+ 181 - 0
vendor_base.cpp

@@ -0,0 +1,181 @@
+#include "vendor_base.h"
+#include "vendor_global.h"
+#include <event.h>
+#include <signal.h>
+
+namespace vendor {
+
+struct event_base *eventBase_ = nullptr;
+
+LongOpts::LongOpts(const MyOpt opts[], const int size)
+{
+    myOpt = opts;
+    sizeOpt = size;
+}
+
+void LongOpts::GetOptions(option *opts, std::string &shorts)
+{
+    for (int i = 0; i < sizeOpt; i++) {
+        // printf("val: %d(%c) ", myOpt[i].val, myOpt[i].val);
+        opts[i].name = strdup(myOpt[i].name);
+        opts[i].has_arg = myOpt[i].has_arg;
+        opts[i].flag = NULL;
+        opts[i].val = myOpt[i].val;
+        if (myOpt[i].val == 0) {
+            continue;
+        }
+        if (myOpt[i].has_arg == no_argument) {
+            shorts.push_back(static_cast<char>(myOpt[i].val));
+        } else if (myOpt[i].has_arg == required_argument) {
+            shorts.push_back(static_cast<char>(myOpt[i].val));
+            shorts.push_back(':');
+        } else {
+            shorts.push_back(static_cast<char>(myOpt[i].val));
+        }
+    }
+}
+
+MyOpt LongOpts::GetOption(char ch, int index)
+{
+    if (ch == 0) {
+        return myOpt[index];
+    }
+
+    for (int i = 0; i < sizeOpt; i++) {
+        if (myOpt[i].val == ch) {
+            return myOpt[i];
+        }
+    }
+    return myOpt[0];
+}
+
+VendorBase::VendorBase()
+{
+    HTELINK_LOG_ENABLE(true);
+    eventBase_ = event_base_new();
+    if (eventBase_ == nullptr) {
+        HTELINK_LOG_ERR("event new failed, %s", strerror(errno));
+    }
+}
+
+VendorBase::~VendorBase()
+{
+    if (eventBase_ == nullptr) {
+        return;
+    }
+    Exit(SIGINT);
+    event_base_free(eventBase_);
+}
+
+int VendorBase::Exec()
+{
+    HTELINK_LOG_INFO("register event...");
+    // 注册信号事件
+    event_add(evsignal_new(eventBase_, SIGSEGV, VendorBase::SignalHandler, this), NULL);
+    event_add(evsignal_new(eventBase_, SIGFPE, VendorBase::SignalHandler, this), NULL);
+    event_add(evsignal_new(eventBase_, SIGINT, VendorBase::SignalHandler, this), NULL);
+    event_add(evsignal_new(eventBase_, SIGTERM, VendorBase::SignalHandler, this), NULL);
+    event_add(evsignal_new(eventBase_, SIGTSTP, VendorBase::SignalHandler, this), NULL);
+
+    signal(SIGPIPE, SIG_IGN);
+
+    HTELINK_LOG_INFO("start to Run");
+    // struct event *timer_ev = event_new(
+    //     eventBase_, -1, EV_PERSIST,
+    //     [](evutil_socket_t ev, short e, void *arg) {
+    //         VendorBase *vendorBase = static_cast<VendorBase *>(arg);
+    //         vendorBase->Run();
+    //     },
+    //     this);
+    // event_add(timer_ev, NULL);
+    std::thread fn([this] {
+        Run();
+    });
+    fn.detach();
+    // 其他业务
+    HTELINK_LOG_INFO("start to deamon...");
+    return event_base_dispatch(eventBase_);
+}
+
+void VendorBase::Exit(int signal)
+{
+    Stop(signal);
+    if (eventBase_ == nullptr) {
+        return;
+    }
+    char dumpFile[VENDOR_MAX_PATH_SIZE];
+    sprintf(dumpFile, "%s/event_stat_%s.txt", VENDOR_LOG_PATH.c_str(), utils::nowtostr().c_str());
+    FILE *fp = fopen(dumpFile, "a");
+    event_base_dump_events(eventBase_, fp);
+    fclose(fp);
+    event_base_loopbreak(eventBase_);
+}
+
+void VendorBase::SignalHandler(int fd, short event, void *arg)
+{
+    if (event != EV_SIGNAL) {
+        HTELINK_LOG_ERR("fd: %d, event: %d occur", fd, event);
+        return;
+    }
+
+    void *l_buffer[512];
+    char **l_ptrace;
+
+    int signal = fd;
+
+    VendorBase *vendorBase = static_cast<VendorBase *>(arg);
+    if (vendorBase) {
+        vendorBase->Exit(signal);
+    }
+
+    HTELINK_LOG_ERR("\r\n=========>>>catch signal %d <<<=========", signal);
+    HTELINK_LOG_ERR("Dump stack start...");
+
+    int size = backtrace(l_buffer, 512);
+    l_ptrace = backtrace_symbols(l_buffer, size);
+    if (NULL == l_ptrace) {
+        HTELINK_LOG_ERR("backtrace_symbols");
+        exit(1);
+    }
+
+    for (int i = 0; i < size; i++) {
+        HTELINK_LOG_ERR("  [%02d] %s", i, l_ptrace[i]);
+    }
+    HTELINK_LOG_ERR("Dump stack end...");
+    free(l_ptrace);
+    exit(signal);
+}
+
+int32_t VendorBase::ParseOptionArgs(VendorBase *vendor, int argc, char *argv[])
+{
+    int longindex = 0;
+    std::string shorts;
+    struct option longopts[vendor->GetOptSize()];
+    LongOpts longOpts(vendor->GetOpts(), vendor->GetOptSize());
+    longOpts.GetOptions(longopts, shorts);
+    int ch;
+    while ((ch = getopt_long(argc, argv, shorts.c_str(), longopts, &longindex)) != -1) {
+        MyOpt myOpt = longOpts.GetOption(ch, longindex);
+        printf("longindex :%d, opt %d(%c), name:%s , optarg :%s\n", longindex, myOpt.val, myOpt.val, myOpt.name,
+            optarg == nullptr ? "nullptr" : optarg);
+        if (strcmp(myOpt.name, "help") == 0) {
+            MyOpt *myOpts = vendor->GetOpts();
+            printf("Usage: %s [OPTION] -l URL\n\nOPTIONS:\n", vendor->Name().c_str());
+            for (int i = 1; i < vendor->GetOptSize(); i++) {
+                if (myOpts[i].val == 0) {
+                    printf("--%s:  %s\n", myOpts[i].name, myOpts[i].desc);
+                } else {
+                    printf("-%c, --%s:  %s\n", myOpts[i].val, myOpts[i].name, myOpts[i].desc);
+                }
+            }
+            return -1;
+        }
+
+        if (vendor->ParseCmdline(myOpt.name, optarg == nullptr ? "" : optarg) != 0) {
+            printf("parse failed!!!\n");
+            return -1;
+        }
+    }
+    return 0;
+}
+}; // namespace vendor

+ 71 - 0
vendor_base.h

@@ -0,0 +1,71 @@
+#ifndef __VENDOR_VENDOR_BASE_H__
+#define __VENDOR_VENDOR_BASE_H__
+#include <condition_variable>
+#include <cstdio>
+#include <execinfo.h>
+#include <fstream>
+#include <functional>
+#include <getopt.h>
+#include <iostream>
+#include <memory>
+#include <mutex>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <thread>
+#include <unistd.h>
+#include <utils/logger.h>
+#include <vector>
+
+namespace vendor {
+
+class VendorBase;
+struct MyOpt {
+    const char *name;
+    int has_arg;
+    int val;
+    const char *desc;
+};
+
+struct LongOpts {
+    const MyOpt *myOpt;
+    int sizeOpt;
+
+    LongOpts(const MyOpt opts[], const int size);
+
+    void GetOptions(struct option *opts, std::string &shorts);
+
+    MyOpt GetOption(char ch, int index);
+};
+
+class VendorBase {
+public:
+    VendorBase();
+    virtual ~VendorBase();
+    static int32_t ParseOptionArgs(VendorBase *vendor, int argc, char *argv[]);
+
+    int Exec();
+    void Exit(int signal);
+
+protected:
+    virtual int ParseCmdline(const std::string &optname, const std::string &optarg) = 0;
+    virtual MyOpt *GetOpts() = 0;
+    virtual int GetOptSize() = 0;
+    virtual void Signal(int signal) {}
+
+public:
+    virtual int Run() = 0;
+    virtual std::string Name() = 0;
+    virtual void Stop(int signal) = 0;
+
+    static void SignalHandler(int fd, short event, void *arg);
+
+private:
+};
+
+} // namespace vendor
+
+#endif // __VENDOR_VENDOR_BASE_H__