commit cb3a6fcd318a95f28401655071698fee6d237d33 Author: SikongJueluo Date: Sun Jun 9 18:24:28 2024 +0800 first commit which could ouput camera video stream diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..b2d18e6 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,3 @@ +FROM localhost/arm-himix200-linux + +RUN apt install unzip diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..6c05639 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,32 @@ +{ + "name": "Hi3516_DEV", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + // "image": "localhost/arm-himix200-linux", + "build" : { + "dockerfile": "Dockerfile" + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "appPort": [ "7897:7897" ], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Configure tool-specific properties. + "customizations": { + "vscode": { + "setting": {}, + "extensions": [ + "ms-vscode.cpptools-extension-pack", + "tboox.xmake-vscode", + "satiromarra.code-sftp" + ] + } + } + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24799ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Xmake cache +.xmake/ +.vscode/ +Hi3516CV500_SDK/ +build/ +Rouring/ +Rouring-Vision/ + +# MacOS Cache +.DS_Store + + diff --git a/Hi3516_SDK.lua b/Hi3516_SDK.lua new file mode 100644 index 0000000..7d8843c --- /dev/null +++ b/Hi3516_SDK.lua @@ -0,0 +1,83 @@ +local lib = "Hi3516CV500_SDK/smp/a7_linux/mpp/lib/" + +target("hi_library") + set_kind("static") + add_includedirs("Hi3516CV500_SDK/smp/a7_linux/mpp/include", "Hi3516CV500_SDK/smp/a7_linux/mpp/include/adapt", {public = true}) + add_linkdirs("Hi3516CV500_SDK/smp/a7_linux/mpp/lib") + + -- isp static library + add_links( + lib.."libisp.a", + lib.."lib_hicalcflicker.a", + {public = true} + ) + + -- mpi static library + add_links( + lib.."libmpi.a", + lib.."libhdmi.a", + {public = true} + ) + + -- audio static library + add_links( + lib.."libVoiceEngine.a", + lib.."libupvqe.a", + lib.."libdnvqe.a", + {public = true} + ) + + -- sensor static library + add_links( + lib.."lib_hiae.a", + lib.."lib_hidehaze.a", + lib.."lib_hidrc.a", + lib.."lib_hildci.a", + lib.."lib_hiawb.a", + lib.."libsns_imx327.a", + lib.."libsns_imx327_2l.a", + lib.."libsns_imx307.a", + lib.."libsns_imx307_2l.a", + lib.."libsns_imx458.a", + lib.."libsns_mn34220.a", + lib.."libsns_os05a.a", + lib.."libsns_os08a10.a", + lib.."libsns_gc2053.a", + lib.."libsns_sc4210.a", + lib.."libsns_ov12870.a", + lib.."libsns_os04b10.a", + lib.."libsns_imx415.a", + lib.."libsns_imx274.a", + lib.."libsns_imx219.a", + {public = true} + ) + + -- single files + add_links( + lib.."libsecurec.a", + lib.."libsns_imx335.a", + "pthread", + "dl", + {public = true} + ) + -- scipt + on_load(function (target) + print(target:get("links")) + end) + +target("sample_audio") + set_kind("static") + add_files("Hi3516CV500_SDK/smp/a7_linux/mpp/sample/audio/adp/*.c") + add_includedirs("Hi3516CV500_SDK/smp/a7_linux/mpp/sample/audio/adp", {public = true}) + add_deps("hi_library") + +target("sample_common") + set_kind("static") + add_files("Hi3516CV500_SDK/smp/a7_linux/mpp/sample/common/*.c") + add_includedirs("Hi3516CV500_SDK/smp/a7_linux/mpp/sample/common", {public = true}) + add_defines( + "SENSOR0_TYPE=GALAXYCORE_GC2053_MIPI_2M_30FPS_10BIT", + "SENSOR1_TYPE=GALAXYCORE_GC2053_MIPI_2M_30FPS_10BIT", + {public = true} + ) + add_deps("sample_audio") \ No newline at end of file diff --git a/src/isp/eb3516_video.c b/src/isp/eb3516_video.c new file mode 100644 index 0000000..3bedb42 --- /dev/null +++ b/src/isp/eb3516_video.c @@ -0,0 +1,290 @@ +#include "eb3516_video.h" + +#include "hi_common.h" +#include "my_common.h" +#include "sample_comm.h" +#include "zlog.h" + +#define VB_YUV_COUNT 10 +#define VB_RGB_COUNT 4 +#define ALIGN_DOWN_SIZE 2 + +typedef struct hiSAMPLE_VPSS_CONFIG_S { + VPSS_GRP s32GrpId; + VPSS_GRP_ATTR_S stGrpAttr; + HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM]; + VPSS_CHN_ATTR_S astChnAttrs[VPSS_MAX_PHY_CHN_NUM]; +} SAMPLE_VPSS_CONFIG_S; + +static zlog_category_t* log = NULL; + +// Sensor Info +static SAMPLE_VI_CONFIG_S g_stViConfig = {0}; +static PIC_SIZE_E enPicSize; +static SIZE_S stSize; +static HI_U32 u32Framerate; + +static VB_CONFIG_S g_stVbConfig = {0}; +static SAMPLE_VPSS_CONFIG_S g_stVpss0Config = {0}; +static SAMPLE_VPSS_CONFIG_S g_stVpss1Config = {0}; + +// 注意此处不能为通道 0, 因为 hi3516 的 VPSS 通道 0 只支持放大, +// 其它通道只支持缩小 +static const VPSS_CHN g_Vpss0Chn[2] = {1, 2}; +static const VPSS_CHN g_Vpss1Chn = 1; +static const PIC_SIZE_E g_PicSizes[3] = {PIC_1080P, PIC_720P, PIC_1080P}; +static const VENC_CHN g_VencChn[1] = {0}; +static const PAYLOAD_TYPE_E g_CodecTypes[3] = {PT_H265, PT_H264, PT_JPEG}; + +static HI_S32 VPSS_GetDefChnAttr(VPSS_CHN_ATTR_S* pstVpssChnAttr, + VPSS_CHN VpssChn, PIC_SIZE_E enPicSize) { + SIZE_S stSize; + SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize); + pstVpssChnAttr->enChnMode = VPSS_CHN_MODE_USER; + pstVpssChnAttr->u32Width = stSize.u32Width; + pstVpssChnAttr->u32Height = stSize.u32Height; + pstVpssChnAttr->enVideoFormat = VIDEO_FORMAT_LINEAR; + pstVpssChnAttr->enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + pstVpssChnAttr->enDynamicRange = DYNAMIC_RANGE_SDR8; + pstVpssChnAttr->enCompressMode = COMPRESS_MODE_NONE; // COMPRESS_MODE_SEG; + pstVpssChnAttr->stFrameRate.s32SrcFrameRate = -1; + pstVpssChnAttr->stFrameRate.s32DstFrameRate = -1; + pstVpssChnAttr->u32Depth = 0; + pstVpssChnAttr->bMirror = HI_FALSE; + pstVpssChnAttr->bFlip = HI_FALSE; + pstVpssChnAttr->stAspectRatio.enMode = ASPECT_RATIO_NONE; + return HI_SUCCESS; +} + +static HI_S32 VPSS_GetParams(SAMPLE_VPSS_CONFIG_S* pstVpssConfig, + SIZE_S* pstMaxSize, HI_BOOL bSnap) { + // 设置 VPSS 组 + pstVpssConfig->s32GrpId = !bSnap ? 0 : 1; + pstVpssConfig->stGrpAttr.u32MaxW = pstMaxSize->u32Width; + pstVpssConfig->stGrpAttr.u32MaxH = pstMaxSize->u32Width; + pstVpssConfig->stGrpAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + pstVpssConfig->stGrpAttr.enDynamicRange = DYNAMIC_RANGE_SDR8; + pstVpssConfig->stGrpAttr.stFrameRate.s32SrcFrameRate = -1; + pstVpssConfig->stGrpAttr.stFrameRate.s32DstFrameRate = -1; + pstVpssConfig->stGrpAttr.bNrEn = HI_TRUE; + pstVpssConfig->stGrpAttr.stNrAttr.enNrType = + !bSnap ? VPSS_NR_TYPE_VIDEO : VPSS_NR_TYPE_SNAP; + pstVpssConfig->stGrpAttr.stNrAttr.enCompressMode = COMPRESS_MODE_FRAME; + pstVpssConfig->stGrpAttr.stNrAttr.enNrMotionMode = NR_MOTION_MODE_NORMAL; + // 设置 VPSS 通道 + if (!bSnap) { + for (HI_S32 i = 0; i < ARRAY_LENGTH(g_Vpss0Chn); i++) { + VPSS_CHN VpssChn = g_Vpss0Chn[i]; + pstVpssConfig->abChnEnable[VpssChn] = HI_TRUE; + VPSS_GetDefChnAttr(&pstVpssConfig->astChnAttrs[VpssChn], VpssChn, + g_PicSizes[i]); + if (i == 1) { + pstVpssConfig->astChnAttrs[VpssChn].u32Depth = 2; + } + } + } else { + VPSS_CHN VpssChn = g_Vpss1Chn; + pstVpssConfig->abChnEnable[VpssChn] = HI_TRUE; + VPSS_GetDefChnAttr(&pstVpssConfig->astChnAttrs[VpssChn], VpssChn, + g_PicSizes[2]); + } + return HI_SUCCESS; +} + +void eb3516VideoInit(void) { + log = zlog_get_category("eb3516_video"); + + // Get Sensor(VI) Info: picture size , frame rate + SAMPLE_COMM_VI_GetSensorInfo(&g_stViConfig); + SAMPLE_COMM_VI_GetSizeBySensor( + g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, &enPicSize); + SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize); + SAMPLE_COMM_VI_GetFrameRateBySensor( + g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, &u32Framerate); + + // 配置图像缓冲区 + g_stVbConfig.u32MaxPoolCnt = 2; + // 获取一帧图片 buffer 的大小 + g_stVbConfig.astCommPool[0].u64BlkSize = COMMON_GetPicBufferSize( + stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_YVU_SEMIPLANAR_422, + DATA_BITWIDTH_8, COMPRESS_MODE_SEG, DEFAULT_ALIGN); + g_stVbConfig.astCommPool[0].u32BlkCnt = VB_YUV_COUNT; + // 获取 raw buffer 的大小 + g_stVbConfig.astCommPool[1].u64BlkSize = VI_GetRawBufferSize( + stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_RGB_BAYER_16BPP, + COMPRESS_MODE_NONE, DEFAULT_ALIGN); + g_stVbConfig.astCommPool[1].u32BlkCnt = VB_RGB_COUNT; + + // 配置 VI + g_stViConfig.s32WorkingViNum = 1; + g_stViConfig.as32WorkingViId[0] = 0; + // 设置 VI 传感器信息 + g_stViConfig.astViInfo[0].stSnsInfo.MipiDev = + SAMPLE_COMM_VI_GetComboDevBySensor( + g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, 0); + + g_stViConfig.astViInfo[0].stDevInfo.ViDev = 0; + g_stViConfig.astViInfo[0].stDevInfo.enWDRMode = WDR_MODE_NONE; + // 设置 VI PIPE 信息 + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = 0; // video pipe + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = -1; // snap pipe + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[2] = -1; + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[3] = -1; + g_stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode = + VI_OFFLINE_VPSS_OFFLINE; + // 设置 VI 通道信息 + g_stViConfig.astViInfo[0].stChnInfo.ViChn = 0; + g_stViConfig.astViInfo[0].stChnInfo.enPixFormat = + PIXEL_FORMAT_YVU_SEMIPLANAR_420; + g_stViConfig.astViInfo[0].stChnInfo.enDynamicRange = DYNAMIC_RANGE_SDR8; + g_stViConfig.astViInfo[0].stChnInfo.enVideoFormat = VIDEO_FORMAT_LINEAR; + g_stViConfig.astViInfo[0].stChnInfo.enCompressMode = COMPRESS_MODE_SEG; + // 设置 VI 抓拍信息 + g_stViConfig.astViInfo[0].stSnapInfo.bSnap = HI_FALSE; + g_stViConfig.astViInfo[0].stSnapInfo.bDoublePipe = HI_TRUE; + g_stViConfig.astViInfo[0].stSnapInfo.VideoPipe = 0; + g_stViConfig.astViInfo[0].stSnapInfo.SnapPipe = -1; + g_stViConfig.astViInfo[0].stSnapInfo.enVideoPipeMode = + VI_OFFLINE_VPSS_OFFLINE; + g_stViConfig.astViInfo[0].stSnapInfo.enSnapPipeMode = + VI_OFFLINE_VPSS_OFFLINE; + + // 配置 VPSS + VPSS_GetParams(&g_stVpss0Config, &stSize, false); + VPSS_GetParams(&g_stVpss1Config, &stSize, true); + + zlog_info(log, "eb3516 Video Init Finish..."); +} + +bool eb3516VideoStart(void) { + HI_S32 s32Ret = 0; + + // 初始化 VB 和 MPI 系统 + s32Ret = SAMPLE_COMM_SYS_InitWithVbSupplement(&g_stVbConfig, + VB_SUPPLEMENT_JPEG_MASK); + if (s32Ret != HI_SUCCESS) { + zlog_error(log, "Init VB and MPI failed with %#x!\n", s32Ret); + goto EXIT_SYS_RST_CLK; + } + + // 启动 VI + s32Ret = SAMPLE_COMM_VI_SetParam(&g_stViConfig); + ISP_CTRL_PARAM_S stIspCtrlParam = {0}; + memset(&stIspCtrlParam, 0, sizeof(stIspCtrlParam)); + s32Ret = HI_MPI_ISP_GetCtrlParam( + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], &stIspCtrlParam); + stIspCtrlParam.u32StatIntvl = u32Framerate / 30; + s32Ret = HI_MPI_ISP_SetCtrlParam( + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], &stIspCtrlParam); + s32Ret = SAMPLE_COMM_VI_StartVi(&g_stViConfig); + if (s32Ret != HI_SUCCESS) { + zlog_error(log, "Start VI failed with %#x!\n", s32Ret); + goto EXIT_SYS_STOP; + } + zlog_info(log, "eb3516 VI Start Success..."); + + // 启动 VPSS + s32Ret = SAMPLE_COMM_VPSS_Start( + g_stVpss0Config.s32GrpId, g_stVpss0Config.abChnEnable, + &g_stVpss0Config.stGrpAttr, g_stVpss0Config.astChnAttrs); + if (s32Ret != HI_SUCCESS) { + zlog_error(log, "Start VPSS group %d failed with %#x!\n", + g_stVpss0Config.s32GrpId, s32Ret); + goto EXIT_VI_STOP; + } + zlog_info(log, "eb3516 VPSS Start Success..."); + + // 绑定 VI->VPSS + s32Ret = SAMPLE_COMM_VI_Bind_VPSS( + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], + g_stViConfig.astViInfo[0].stChnInfo.ViChn, g_stVpss0Config.s32GrpId); + if (s32Ret != HI_SUCCESS) { + zlog_error(log, "VI Video Pipe bind VPSS failed with %#x!\n", s32Ret); + goto EXIT_VPSS_STOP; + } + + + // Get Venc Config + VENC_GOP_ATTR_S stGopAttr; + SAMPLE_COMM_VENC_GetGopAttr(VENC_GOPMODE_NORMALP, &stGopAttr); + + // 编码 h.265 4k + s32Ret = + SAMPLE_COMM_VENC_Creat(g_VencChn[0], g_CodecTypes[0], g_PicSizes[0], + SAMPLE_RC_VBR, 0, HI_FALSE, &stGopAttr); + if (s32Ret != HI_SUCCESS) { + zlog_error(log, "Create Venc Chn %d failed with %#x!\n", g_VencChn[0], + s32Ret); + goto EXIT_VI_VPSS_UNBIND; + } + zlog_info(log, "eb3516 VENC Start Success..."); + + /*config vo*/ + SAMPLE_VO_CONFIG_S stVoConfig; + SAMPLE_COMM_VO_GetDefConfig(&stVoConfig); + stVoConfig.enDstDynamicRange = DYNAMIC_RANGE_SDR8; + stVoConfig.enVoIntfType = VO_INTF_HDMI; + stVoConfig.enPicSize = enPicSize; + + /*start vo*/ + s32Ret = SAMPLE_COMM_VO_StartVO(&stVoConfig); + if (HI_SUCCESS != s32Ret) + { + SAMPLE_PRT("start vo failed. s32Ret: 0x%x !\n", s32Ret); + goto EXIT_VENC_H264_STOP; + } + zlog_info(log, "eb3516 VO Start Success..."); + + /*vpss bind vo*/ + s32Ret = SAMPLE_COMM_VPSS_Bind_VO(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0], stVoConfig.VoDev, g_VencChn[0]); + if (HI_SUCCESS != s32Ret) + { + SAMPLE_PRT("vo bind vpss failed. s32Ret: 0x%x !\n", s32Ret); + goto EXIT_VO_STOP; + } + + + // // 绑定 VPSS[0,0]->VENC[0] + // s32Ret = SAMPLE_COMM_VPSS_Bind_VENC(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0], + // g_VencChn[0]); + // if (s32Ret != HI_SUCCESS) { + // zlog_error(log, "Venc bind Vpss failed with %#x!\n", s32Ret); + // goto EXIT_VENC_H265_STOP; + // } + + // Start Venc Stream + // s32Ret = SAMPLE_COMM_VENC_StartGetStream( + // g_VencChn + 1, sizeof(g_VencChn) / sizeof(VENC_CHN) - 2); + // if (HI_SUCCESS != s32Ret) { + // zlog_error(log, "Get venc stream failed!\n"); + // goto EXIT_VENC_H264_STOP; + // } + // zlog_info(log, "eb3516 Stream Start Success..."); + + PAUSE(); + + // SAMPLE_COMM_VENC_StopGetStream(); + zlog_info(log, "Exit process Sucessfully!"); + + +EXIT_VO_STOP: + SAMPLE_COMM_VO_StopVO(&stVoConfig); +EXIT_VENC_H264_STOP: + SAMPLE_COMM_VENC_Stop(g_VencChn[1]); +EXIT_VENC_H265_STOP: + // SAMPLE_COMM_VENC_Stop(g_VencChn[0]); +EXIT_VI_VPSS_UNBIND: + SAMPLE_COMM_VI_UnBind_VPSS(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], + g_stViConfig.astViInfo[0].stChnInfo.ViChn, + g_stVpss0Config.s32GrpId); +EXIT_VPSS_STOP: + SAMPLE_COMM_VPSS_Stop(g_stVpss0Config.s32GrpId, + g_stVpss0Config.abChnEnable); +EXIT_VI_STOP: + SAMPLE_COMM_VI_StopVi(&g_stViConfig); +EXIT_SYS_STOP: + SAMPLE_COMM_SYS_Exit(); +EXIT_SYS_RST_CLK: +EXIT: + return s32Ret; +} \ No newline at end of file diff --git a/src/isp/eb3516_video.h b/src/isp/eb3516_video.h new file mode 100644 index 0000000..ed762f7 --- /dev/null +++ b/src/isp/eb3516_video.h @@ -0,0 +1,17 @@ +#ifndef __EB3516_VIDEO_H__ +#define __EB3516_VIDEO_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "stdbool.h" + +void eb3516VideoInit(void); +bool eb3516VideoStart(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/log.conf b/src/log.conf new file mode 100644 index 0000000..368338d --- /dev/null +++ b/src/log.conf @@ -0,0 +1,16 @@ +[global] + +strict init = true +default format = "%d [%V] %m%n" + +[formats] + +simple = "[%V] %m%n" +detail = "[%d.%us] [%p:%F:%L] [%V] %m%n" + +[rules] + +*.ERROR >stdout; detail +*.WARN >stdout; +*.INFO >stdout; simple +*.DEBUG "log/%c.log"; detail diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..83df009 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "hi_common.h" +#include "zlog.h" + +#include "isp/eb3516_video.h" + +int main(int argc, char** argv) { + int result = 0; + std::error_code file_error; + + zlog_category_t *log = nullptr; + + // init log and check log.conf + result = zlog_init("log.conf"); + if (result) { + std::cout << "zlog init failed! Please check log.conf!\n"; + return (-1); + } + + // get log cat for main to print + log = zlog_get_category("cat"); + if (!log) { + std::cout << "Main get log failed!\n"; + return (-2); + } + zlog_info(log, "Init zlog Sucessfully"); + + // if (!std::experimental::filesystem::remove_all("log", file_error)) { + // zlog_warn(log, "Can't Remove Last Logs FOR %s", file_error.message().c_str()); + // } + + if (!std::experimental::filesystem::create_directory("log", file_error)) { + zlog_warn(log, "Can't Create log dir FOR %s", file_error.message().c_str()); + } + + eb3516VideoInit(); + eb3516VideoStart(); + + zlog_fini(); + + return 0; +} diff --git a/src/my_common.h b/src/my_common.h new file mode 100644 index 0000000..9baf9e1 --- /dev/null +++ b/src/my_common.h @@ -0,0 +1,8 @@ +#ifndef __MY_COMMON_H__ +#define __MY_COMMON_H__ + +#ifndef ARRAY_LENGTH +#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0])) +#endif + +#endif \ No newline at end of file diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..d451cb7 --- /dev/null +++ b/xmake.lua @@ -0,0 +1,100 @@ +add_rules("mode.debug", "mode.release") +includes("Hi3516_SDK.lua") + +set_config("sdk", "/opt/hisi-linux/x86-arm/arm-himix200-linux/") +set_languages("c11", "c++14") +add_requires("zlog 1.2.17") + +target("ISP") + set_kind("static") + add_files("src/isp/*.c") + add_includedirs("src") + add_deps("sample_common") + add_packages("zlog") + +target("CatFeeder") + set_kind("binary") + add_includedirs("src") + add_files("src/*.cpp") + add_deps("hi_library", "ISP") + add_packages("zlog") + add_links("stdc++fs") + after_build(function (target) + os.cp("src/log.conf", "$(buildir)/cross/arm/release") + end) + +if is_mode("debug") then + add_defines("DEBUG") + set_symbols("debug") + set_optimize("none") +end + +-- +-- If you want to known more usage about xmake, please see https://xmake.io +-- +-- ## FAQ +-- +-- You can enter the project directory firstly before building project. +-- +-- $ cd projectdir +-- +-- 1. How to build project? +-- +-- $ xmake +-- +-- 2. How to configure project? +-- +-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release] +-- +-- 3. Where is the build output directory? +-- +-- The default output directory is `./build` and you can configure the output directory. +-- +-- $ xmake f -o outputdir +-- $ xmake +-- +-- 4. How to run and debug target after building project? +-- +-- $ xmake run [targetname] +-- $ xmake run -d [targetname] +-- +-- 5. How to install target to the system directory or other output directory? +-- +-- $ xmake install +-- $ xmake install -o installdir +-- +-- 6. Add some frequently-used compilation flags in xmake.lua +-- +-- @code +-- -- add debug and release modes +-- add_rules("mode.debug", "mode.release") +-- +-- -- add macro definition +-- add_defines("NDEBUG", "_GNU_SOURCE=1") +-- +-- -- set warning all as error +-- set_warnings("all", "error") +-- +-- -- set language: c99, c++11 +-- set_languages("c99", "c++11") +-- +-- -- set optimization: none, faster, fastest, smallest +-- set_optimize("fastest") +-- +-- -- add include search directories +-- add_includedirs("/usr/include", "/usr/local/include") +-- +-- -- add link libraries and search directories +-- add_links("tbox") +-- add_linkdirs("/usr/local/lib", "/usr/lib") +-- +-- -- add system link libraries +-- add_syslinks("z", "pthread") +-- +-- -- add compilation and link flags +-- add_cxflags("-stdnolib", "-fno-strict-aliasing") +-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true}) +-- +-- @endcode +-- +