commit 4333c8d31b65de6d89997d37c752bf5347a026be Author: 崔一鸣 Date: Wed Apr 17 14:30:11 2019 +0800 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75ec3f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bbf8ca0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.5) +project(lun_sapp) + +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) +#include(Version) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_C_STANDARD 11) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set (CMAKE_CXX_FLAGS "-Wall") +SET(CMAKE_BUILD_TYPE Debug) + +add_definitions(-D_GNU_SOURCE) + +if (CMAKE_BUILD_TYPE STREQUAL Debug) + add_definitions(-DDEBUG) +endif() + +add_subdirectory(vendor) +add_subdirectory(test) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..5797582 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,15 @@ +### test_coroutine +add_executable(test_coroutine test_coroutine/main.cpp) +#target_include_directories(test_coroutine PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) +target_link_libraries(test_coroutine lua-static dl) + + +### test_plugin +add_library(http_service SHARED test_plugin/http_service.cpp) +#target_include_directories(http_service PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) +target_link_libraries(http_service MESA_handle_logger MESA_htable MESA_prof_load) + +### new_http_service +add_library(new_http_service SHARED new_http_service/adapter.cpp) +#target_include_directories(new_http_service PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) +target_link_libraries(new_http_service lua-static dl MESA_handle_logger MESA_htable MESA_prof_load) \ No newline at end of file diff --git a/test/new_http_service/adapter.cpp b/test/new_http_service/adapter.cpp new file mode 100644 index 0000000..fb37e32 --- /dev/null +++ b/test/new_http_service/adapter.cpp @@ -0,0 +1,270 @@ +#include "adapter.h" + +#define LOG_MODULE_NAME "SAPP_LUA" +#define LUA_SAPP_SYMBOL_MAX 64 +#define LUA_SAPP_PATH_MAX 256 +#define LUA_SAPP_STRING_MAX 2048 +#define LUA_ENTRY_TYPE_NUM 8 +enum lua_entry_type{ + LUA_ENTRY_TYPE_IP = 0, + LUA_ENTRY_TYPE_TCP, + LUA_ENTRY_TYPE_UDP, + LUA_ENTRY_TYPE_HTTP, + LUA_ENTRY_TYPE_TLS, + LUA_ENTRY_TYPE_DNS, + LUA_ENTRY_TYPE_MAIL, + LUA_ENTRY_TYPE_FTP, +}; + + +//TODO: +// other_regions 有多个, 怎么处理 +// 增加根据region返回header功能 + +class lua_plug{ +public: + std::string file_path; + enum lua_entry_type entry_type; + int dir; + std::unordered_set regions; + lua_State *lua_state; +}; + +static void* g_logger = NULL; +static std::vector> g_lua_plugs(LUA_ENTRY_TYPE_NUM, std::vector()); + +//copy from suricata +static int lua_push_string_buffer(lua_State *lua_state, const char *input, size_t input_len) +{ + if (input_len % 4 != 0) { + /* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates + * invalid read errors in valgrind otherwise. Adding in a nul to be sure. + * Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */ + size_t buflen = input_len + 1 + ((input_len + 1) % 4); + char buf[buflen]; + memset(buf, 0x00, buflen); + memcpy(buf, input, input_len); + buf[input_len] = '\0'; + /* return value through lua_state, as a luastring */ + lua_pushlstring(lua_state, buf, input_len); + } else { + lua_pushlstring(lua_state, input, input_len); + } + return 1; +} + + +static int _get_http_headers(lua_State *lua_state, int status, lua_KContext yieldk_ctx){ + lua_getglobal(lua_state, "cur_http_sess_ctx"); + http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1); + lua_getglobal(lua_state, "cur_http_sess_dir"); + int curdir = (int)lua_tonumber(lua_state, -1); + lua_pop(lua_state, 2); + if(sess_ctx == NULL){ + //do log + std::cout<<"sess_ctx is null"<request_headers : sess_ctx->response_headers){ + lua_push_string_buffer(lua_state, header.first.c_str(), header.first.length() + 1); + lua_push_string_buffer(lua_state, header.second.c_str(), header.second.length() + 1); + lua_settable(lua_state, -3); + } + //return 1 means one return value + return 1; +} + +static int get_http_headers(lua_State *lua_state){ + lua_yieldk(lua_state, 0, 0, _get_http_headers); + return 1; +} + +int regions_parse(char *str, std::unordered_set& regions){ + char *token; + char *rest = str; + while((token = strtok_r(rest, ",", &rest))){ + std::string _token = std::string(token); + if(_token == "all"){ + regions.clear(); + regions.insert(_token); + return 0; + } + regions.insert(_token); + } + return 0; +} + +static int load_lua_plug(const char *profile){ + std::unordered_map type_map = { + {"ip", LUA_ENTRY_TYPE_IP}, + {"tcp", LUA_ENTRY_TYPE_TCP}, + {"udp", LUA_ENTRY_TYPE_UDP}, + {"http", LUA_ENTRY_TYPE_HTTP}, + {"tls", LUA_ENTRY_TYPE_TLS}, + {"dns", LUA_ENTRY_TYPE_DNS}, + {"mail", LUA_ENTRY_TYPE_MAIL}, + {"ftp", LUA_ENTRY_TYPE_FTP} + }; + std::unordered_map dir_map{ + {"c2s", DIR_C2S}, + {"s2c", DIR_S2C}, + {"all", DIR_DOUBLE} + }; + const char *section = "main"; + char file_path[LUA_SAPP_PATH_MAX] = ""; + char entry_type[LUA_SAPP_SYMBOL_MAX] = ""; + char dir[LUA_SAPP_SYMBOL_MAX] = ""; + char regions[LUA_SAPP_STRING_MAX] = ""; + MESA_load_profile_string_def(profile, section, "file_path", file_path, sizeof(file_path), ""); + MESA_load_profile_string_def(profile, section, "entry_type", entry_type, sizeof(entry_type), "http"); + MESA_load_profile_string_def(profile, section, "dir", dir, sizeof(dir), "all"); + MESA_load_profile_string_def(profile, section, "regions", regions, sizeof(regions), "all"); + + lua_State *lua_state = luaL_newstate(); + luaL_openlibs(lua_state); + luaL_dofile(lua_state, file_path); + lua_register(lua_state, "get_http_headers", get_http_headers); + lua_getglobal(lua_state, "main"); + + lua_plug plug; + plug.file_path = std::string(file_path); + plug.entry_type = (enum lua_entry_type)type_map[std::string(entry_type)]; + plug.dir = dir_map[std::string(dir)]; + regions_parse(regions, plug.regions); + plug.lua_state = lua_state; + g_lua_plugs[plug.entry_type].push_back(plug); + lua_resume(lua_state, NULL, 0); + return 0; +} + +int process_lua_plug_conflist(const char* filename) +{ + char lua_plug_conf_path[LUA_SAPP_PATH_MAX] = {0}; + FILE* fp = fopen(filename, "r"); + if(fp == NULL){ + MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "process_conflist() fopen %s error!\n", filename); + return -1; + } + while(feof(fp) == 0){ + if((fgets(lua_plug_conf_path, LUA_SAPP_PATH_MAX, fp)) == NULL){ + fclose(fp); + fp=NULL; + return 0; + } + if(lua_plug_conf_path[0]=='#'){ + continue; + } + int len = strnlen(lua_plug_conf_path, LUA_SAPP_PATH_MAX); + lua_plug_conf_path[len - 1] = '\0'; + load_lua_plug(lua_plug_conf_path); + } + fclose(fp); + fp=NULL; + return 0; +} + +static http_sess_ctx* init_http_sess_ctx(){ + http_sess_ctx *ctx = new http_sess_ctx(); + return ctx; +} + +static void clear_http_sess_ctx(http_sess_ctx *ctx){ + delete ctx; + ctx = NULL; +} + +static std::string trans_to_binary(unsigned int n){ + std::string res; + while(n){ + res = std::to_string(n % 2) + res; + n /= 2; + } + return res; +} + +static void output_stack_size(lua_State *lua_state){ + int n = lua_gettop(lua_state); + std::cout<<"stack size is "<app_info); + //static int header_len = 0; + //static int content_len = 0; + if(NULL==session_info){ + return PROT_STATE_DROPME; + } + if(ctx == NULL){ + ctx = init_http_sess_ctx(); + *param = ctx; + } + std::string prot_flag_str = trans_to_binary(session_info->prot_flag); + //MESA_handle_runtime_log(g_logger, RLOG_LV_INFO, HTTP_SERVICE_PLUGNAME, + // "call http_service entry, http_state is %02x\n, prot_flag mask is %s : %d", http_state, prot_flag_str.c_str(), prot_flag_str.length() - 1); + std::string temp = (a_http->http_state == HTTP_DATA_BEGIN) ? "data begin" : "not data begin"; + //curdir: request or response + uchar curdir = a_http->curdir; + switch(session_info->prot_flag) + { + case HTTP_STATE: + case HTTP_CONTENT: + break; + case HTTP_UNGZIP_CONTENT: + //fwrite(session_info->buf, session_info->buflen, 1, service_pme->fp); + //fflush(service_pme->fp); + break; + default: + std::string key(http_proto_flag2region(session_info->prot_flag)); + std::string value((const char*)(session_info->buf), session_info->buflen); + if(curdir == DIR_C2S){ + ctx->request_headers.insert({key, value}); + } + else{ + ctx->response_headers.insert({key, value}); + } + break; + } + uchar http_state = a_http->http_state; + //header over, resume lua + if(http_state == HTTP_DATA_BEGIN){ + for(auto plug : g_lua_plugs[LUA_ENTRY_TYPE_HTTP]){ + if(plug.dir == DIR_DOUBLE || plug.dir == curdir){ + lua_pushlightuserdata(plug.lua_state, (void *)ctx); + lua_setglobal(plug.lua_state, "cur_http_sess_ctx"); + lua_pushinteger(plug.lua_state, curdir); + lua_setglobal(plug.lua_state, "cur_http_sess_dir"); + lua_resume(plug.lua_state, NULL, 0); + } + } + } + if(session_info->session_state & SESSION_STATE_CLOSE){ + clear_http_sess_ctx(ctx); + *param = NULL; + } + return rec; +} + +int NEW_HTTP_SERVICE_INIT(void) +{ + g_logger = MESA_create_runtime_log_handle("./log/http/http_service", 10); + if(g_logger == NULL){ + printf("%s init : get log handle error!\n", HTTP_SERVICE_PLUGNAME); + return -1; + } + // get thread num + // get all business lua script which register http + const char *conflist_path = "./plug/lua/conflist_lua.inf"; + if(g_lua_plugs[LUA_ENTRY_TYPE_HTTP].size() == 0){ + process_lua_plug_conflist(conflist_path); + } + return 0; +} + +void NEW_HTTP_SERVICE_DESTROY(void) +{ + return ; +} + diff --git a/test/new_http_service/adapter.h b/test/new_http_service/adapter.h new file mode 100644 index 0000000..dfdb981 --- /dev/null +++ b/test/new_http_service/adapter.h @@ -0,0 +1,61 @@ +/* + * HTTP_Service.h + * + * Created on: 2013-8-19 + * Author: lishu + */ + +#ifndef HTTP_SERVICE_H_ +#define HTTP_SERVICE_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stream.h" +#include "http.h" +#include "MESA/MESA_prof_load.h" +#include "MESA/MESA_handle_logger.h" + +extern "C" { + #include "lua.h" + #include "lualib.h" + #include "lauxlib.h" +} +#define HTTP_SERVICE_PLUGNAME "new_http_service.so" +#define LOG_PATH "./log/new_http_service/" + + +class http_sess_ctx{ +public: + std::unordered_map request_headers; + std::unordered_map response_headers; +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet); +int NEW_HTTP_SERVICE_INIT(void); +void NEW_HTTP_SERVICE_DESTROY(void); + +#ifdef __cplusplus +} +#endif + +#endif /* HTTP_SERVICE_H_ */ diff --git a/test/new_http_service/http_service.lua b/test/new_http_service/http_service.lua new file mode 100644 index 0000000..58f1b81 --- /dev/null +++ b/test/new_http_service/http_service.lua @@ -0,0 +1,14 @@ +function main() + while true do + headers = get_http_request_headers(ctx) + for k, v in pairs(headers) do + print(k, v) + end + end +end + + +function main() + headers = get_http_request_headers() + content = get_http_content() + ---handle \ No newline at end of file diff --git a/test/test_coroutine/main.cpp b/test/test_coroutine/main.cpp new file mode 100644 index 0000000..931d562 --- /dev/null +++ b/test/test_coroutine/main.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#include +using namespace std; +extern "C" { + #include "lua.h" + #include "lualib.h" + #include "lauxlib.h" +} + +static void output_stack_size(lua_State *L){ + int n = lua_gettop(L); + cout<<"stack size is "< 2){ + max_state_num = atoi(argv[1]); + max_coroutine_num = atoi(argv[2]); + } + const char *filename = "../../test/test_coroutine/test.lua"; + vector states; + for(int i = 0; i < max_state_num; i++){ + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + luaL_dofile(L, filename); + states.push_back(L); + } + vector> coroutines; + for(auto state : states){ + int i = 0; + for(; i < max_coroutine_num; i++){ + lua_State* l = lua_newthread(state); + int ret = lua_checkstack(state, 1); + if(ret != 1) + printf("do not have enough space, ret is %d\n", ret); + coroutines.push_back({l, state}); + lua_getglobal(l, "test"); + //cout<<"after getglobal, size = "< +#include +#include +#include +#include +#include +#include +#include "http_service.h" +#include "MESA_handle_logger.h" + +int HTTP_SERVICE_VERSION_1_20160412 = 0; +void http_service_version_1_20160412() +{ + //20160412 create project +} + +void* g_log_handle = NULL; + +int init_pmeinfo(service_pmeinfo **service_pme, int thread_seq) +{ + service_pmeinfo* pme = (service_pmeinfo*)dictator_malloc(thread_seq, sizeof(service_pmeinfo)); + *service_pme = pme; + return 0; +} + +void clear_pmeinfo(service_pmeinfo *service_pme, int thread_seq) +{ + if(service_pme!=NULL) + { + dictator_free(thread_seq, service_pme); + } + service_pme = NULL; +} + +std::string trans_to_binary(unsigned int n){ + std::string res; + while(n){ + res = std::to_string(n % 2) + res; + n /= 2; + } + return res; +} + +uchar HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet) +{ + uchar rec = PROT_STATE_GIVEME; + service_pmeinfo *service_pme = (service_pmeinfo*)*param; + http_infor *a_http = (http_infor *)(session_info->app_info); + char filename[512] = {0}; + const char* region = NULL; + //static int header_len = 0; + //static int content_len = 0; + + uchar http_state = a_http->http_state; + + if(NULL==session_info) + { + return PROT_STATE_DROPME; + } + + if(service_pme == NULL) + { + if(init_pmeinfo(&service_pme, thread_seq) <0) + { + return PROT_STATE_DROPME; + } + *param = service_pme; + } + std::string prot_flag_str = trans_to_binary(session_info->prot_flag); + MESA_handle_runtime_log(g_log_handle, RLOG_LV_INFO, HTTP_SERVICE_PLUGNAME, + "call http_service entry, http_state is %02x\n, prot_flag mask is %s : %d", http_state, prot_flag_str.c_str(), prot_flag_str.length() - 1); + switch(session_info->prot_flag) + { + case HTTP_STATE: + case HTTP_CONTENT: + break; + case HTTP_UNGZIP_CONTENT: + snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq); + service_pme->fp = fopen(filename, "a+"); + if(NULL==service_pme->fp) + { + MESA_handle_runtime_log(g_log_handle, RLOG_LV_FATAL, HTTP_SERVICE_PLUGNAME, "%s file open error.", filename); + return PROT_STATE_DROPME; + } + MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file open.",filename); + + fwrite(session_info->buf, session_info->buflen, 1, service_pme->fp); + fflush(service_pme->fp); + //content_len += session_info->buflen; + //printf("content_len:%d\n", content_len); + + snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq); + MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file close.",filename); + fclose(service_pme->fp); + break; + default: + snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq); + service_pme->fp = fopen(filename, "a+"); + if(NULL==service_pme->fp) + { + MESA_handle_runtime_log(g_log_handle, RLOG_LV_FATAL, HTTP_SERVICE_PLUGNAME, "%s file open error.", filename); + return PROT_STATE_DROPME; + } + MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file open.",filename); + + region = http_proto_flag2region(session_info->prot_flag); + + fwrite(region, strlen(region), 1, service_pme->fp); + fwrite(":", 1, 1, service_pme->fp); + fwrite(session_info->buf, session_info->buflen, 1, service_pme->fp); + fwrite("\r\n", 2, 1, service_pme->fp); + fflush(service_pme->fp); + //header_len += session_info->buflen; + //printf("header_len:%d\n", header_len); + + snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq); + MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file close.",filename); + fclose(service_pme->fp); + break; + } + + if(session_info->session_state&SESSION_STATE_CLOSE) + { + if(NULL!=service_pme->fp) + { + + service_pme->fp = NULL; + } + clear_pmeinfo((service_pmeinfo*)*param, thread_seq); + *param = NULL; + } + return rec; +} + +int HTTP_SERVICE_INIT(void) +{ + g_log_handle = MESA_create_runtime_log_handle("./log/http/http_service", 10); + if(g_log_handle == NULL) + { + printf("%s init : get log handle error!\n", HTTP_SERVICE_PLUGNAME); + return -1; + } + return 0; +} + +void HTTP_SERVICE_DESTROY(void) +{ + return ; +} + diff --git a/test/test_plugin/http_service.h b/test/test_plugin/http_service.h new file mode 100644 index 0000000..5d0d423 --- /dev/null +++ b/test/test_plugin/http_service.h @@ -0,0 +1,51 @@ +/* + * HTTP_Service.h + * + * Created on: 2013-8-19 + * Author: lishu + */ + +#ifndef HTTP_SERVICE_H_ +#define HTTP_SERVICE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "stream.h" +#include "http.h" + +#define HTTP_SERVICE_PLUGNAME "http_service.so" +#define LOG_PATH "./log/http/" + + +typedef struct service_pmeinfo +{ + FILE* fp; +}service_pmeinfo; + + +#ifdef __cplusplus +extern "C" { +#endif + +uchar HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet); +int HTTP_SERVICE_INIT(void); +void HTTP_SERVICE_DESTROY(void); + +#ifdef __cplusplus +} +#endif + +#endif /* HTTP_SERVICE_H_ */ diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt new file mode 100644 index 0000000..33aea31 --- /dev/null +++ b/vendor/CMakeLists.txt @@ -0,0 +1,47 @@ +include(ExternalProject) + +### lua-5.3.5 +ExternalProject_Add(lua + PREFIX lua + URL ${CMAKE_CURRENT_SOURCE_DIR}/lua-5.3.5.tar.gz + URL_MD5 184779090118aebdf125fdb1233335ea + CONFIGURE_COMMAND cd ./src + BUILD_COMMAND make linux + INSTALL_COMMAND make install INSTALL_TOP= + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(lua INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(lua-static STATIC IMPORTED GLOBAL) +set_property(TARGET lua-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/liblua.a) +set_property(TARGET lua-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + + +### MESA Framework +set(MESA_FRAMEWORK_LIB_DIR /opt/MESA/lib) +set(MESA_FRAMEWORK_INCLUDE_DIR /opt/MESA/include) + +add_library(MESA_handle_logger SHARED IMPORTED GLOBAL) +set_property(TARGET MESA_handle_logger PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_handle_logger.so) +set_property(TARGET MESA_handle_logger PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(MESA_prof_load SHARED IMPORTED GLOBAL) +set_property(TARGET MESA_prof_load PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_prof_load.so) +set_property(TARGET MESA_prof_load PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(wiredcfg SHARED IMPORTED GLOBAL) +set_property(TARGET wiredcfg PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libwiredcfg.so) +set_property(TARGET wiredcfg PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(MESA_htable SHARED IMPORTED GLOBAL) +set_property(TARGET MESA_htable PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_htable.so) +set_property(TARGET MESA_htable PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(maatframe SHARED IMPORTED GLOBAL) +set_property(TARGET maatframe PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libmaatframe.so) +set_property(TARGET maatframe PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) + +add_library(MESA_field_stat SHARED IMPORTED GLOBAL) +set_property(TARGET MESA_field_stat PROPERTY IMPORTED_LOCATION ${MESA_FRAMEWORK_LIB_DIR}/libMESA_field_stat2.so) +set_property(TARGET MESA_field_stat PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MESA_FRAMEWORK_INCLUDE_DIR}) \ No newline at end of file diff --git a/vendor/lua-5.3.5.tar.gz b/vendor/lua-5.3.5.tar.gz new file mode 100644 index 0000000..90c0027 Binary files /dev/null and b/vendor/lua-5.3.5.tar.gz differ