host.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. -- Host (linux) targets for unit and fuzz.
  2. -- 统一构建配置:两个 target 共享同一套流程,仅通过 isFuzz 切换差异
  3. local function setupRyanJsonTarget(isFuzz)
  4. set_kind("binary")
  5. -- 编译工具链与平台配置
  6. set_toolchains("clang")
  7. set_plat("linux")
  8. set_arch("x86")
  9. set_languages("gnu99")
  10. -- 编译优化策略
  11. set_policy("build.ccache", false)
  12. set_optimize("fastest")
  13. -- 警告设置:启用所有警告(Clang 下相当于 -Weverything)
  14. set_warnings("everything")
  15. -- 三个核心配置宏支持由环境变量覆盖:
  16. -- RYANJSON_STRICT_OBJECT_KEY_CHECK
  17. -- RYANJSON_DEFAULT_ADD_AT_HEAD
  18. -- RYANJSON_SNPRINTF_SUPPORT_SCIENTIFIC
  19. local strictObjectKeyCheck = getBooleanEnvDefineValue("RYANJSON_STRICT_OBJECT_KEY_CHECK", "false")
  20. local defaultAddAtHead = getBooleanEnvDefineValue("RYANJSON_DEFAULT_ADD_AT_HEAD", "false")
  21. local snprintfSupportScientific = getBooleanEnvDefineValue("RYANJSON_SNPRINTF_SUPPORT_SCIENTIFIC", "false")
  22. local unitOnlyMemory = getBooleanEnvDefineValue("RYANJSON_UNIT_ONLY_MEMORY", "false")
  23. local unitOnlyRfc8259 = getBooleanEnvDefineValue("RYANJSON_UNIT_ONLY_RFC8259", "false")
  24. add_defines("RyanJsonStrictObjectKeyCheck=" .. strictObjectKeyCheck)
  25. add_defines("RyanJsonDefaultAddAtHead=" .. defaultAddAtHead)
  26. -- 声明 snprintf 支持科学计数法,影响 double 序列化策略
  27. add_defines("RyanJsonSnprintfSupportScientific=" .. snprintfSupportScientific)
  28. if "true" == unitOnlyMemory then
  29. add_defines("RyanJsonUnitOnlyMemory")
  30. end
  31. if "true" == unitOnlyRfc8259 then
  32. add_defines("RyanJsonUnitOnlyRfc8259")
  33. end
  34. -- 启用 Linux 测试环境分支(用于主机侧测试/兼容代码路径)
  35. add_defines("RyanJsonLinuxTestEnv")
  36. add_defines("RyanJsonTestPlatformLinuxFreeRtos")
  37. add_defines("RyanJsonFreeRtosHeap4")
  38. -- 向代码注入项目根目录,供测试与样例定位资源
  39. add_defines("RyanJsonProjectRootPath=\"$(projectdir)\"")
  40. -- 让 Unity 使用项目自定义配置头
  41. add_defines("UNITY_INCLUDE_CONFIG_H")
  42. -- 测试分配模拟参数(可选):用于评估不同 malloc 头部与对齐策略的影响。
  43. tryAddNumericEnvDefine("RYANJSON_TEST_ALLOC_HEADER_SIZE", "RyanJsonTestAllocHeaderSize", 0)
  44. tryAddNumericEnvDefine("RYANJSON_TEST_ALLOC_ALIGN_SIZE", "RyanJsonTestAllocAlignSize", 1)
  45. -- add_defines("RyanJsonEnableAssert")
  46. -- fuzz 专用差异:启用 libFuzzer 宏与链接参数(会注入 main)
  47. if isFuzz then
  48. add_defines("isEnableFuzzer")
  49. -- 编译期启用 libFuzzer 插桩
  50. add_cxflags("-fsanitize=fuzzer", {force = true})
  51. -- 链接期注入 libFuzzer runtime(包含 fuzz main)
  52. add_ldflags("-fsanitize=fuzzer", {force = true})
  53. end
  54. -- 覆盖率相关
  55. add_cxflags(
  56. "-fprofile-instr-generate", -- 生成原始 profile 数据
  57. "-fcoverage-mapping", -- 生成源码到覆盖率映射
  58. {force = true}
  59. )
  60. add_ldflags(
  61. "-fprofile-instr-generate", -- 链接覆盖率 runtime
  62. "-fcoverage-mapping", -- 链接覆盖率映射支持
  63. {force = true}
  64. )
  65. -- 链接器安全硬化与优化选项
  66. add_ldflags(
  67. "-flto", -- 链接时优化(跨文件优化)
  68. "-fPIE", -- 生成位置无关可执行代码
  69. "-pie", -- 启用 PIE 可执行文件
  70. "-fno-omit-frame-pointer", -- 保留栈帧,便于回溯定位
  71. "-fstack-clash-protection",-- 栈碰撞防护
  72. "-Wl,-z,relro", -- 重定位表只读保护
  73. "-Wl,-z,now", -- 启动时完成符号绑定
  74. "-Wl,-z,noexecstack", -- 栈不可执行
  75. "-Wl,-z,separate-code", -- 代码段与数据段分离
  76. {force = true}
  77. )
  78. add_syslinks("pthread")
  79. -- 主机侧统一开启 Sanitizer
  80. add_cxflags(
  81. "-fsanitize=alignment", -- 检测未对齐内存访问
  82. "-fno-sanitize-recover=undefined", -- UB 触发后立即终止
  83. {force = true}
  84. )
  85. add_ldflags(
  86. "-fsanitize=alignment", -- 未对齐访问检查
  87. "-fno-sanitize-recover=undefined", -- UB 触发后立即终止
  88. "-fsanitize=address", -- 越界/UAF 等内存错误
  89. "-fsanitize=leak", -- 泄漏检测
  90. "-fsanitize=undefined", -- 常见未定义行为检测
  91. "-fsanitize=pointer-compare", -- 非法指针比较
  92. "-fsanitize=pointer-subtract", -- 非法指针相减
  93. "-fsanitize=bounds", -- 数组/边界检查
  94. "-fsanitize=float-divide-by-zero", -- 浮点除零检查
  95. "-fsanitize=float-cast-overflow", -- 浮点转整型溢出检查
  96. {force = true}
  97. )
  98. -- 编译器警告与静态分析
  99. add_cxflags(
  100. -- 调试与标准一致性
  101. "-g3", -- 生成详细调试信息
  102. "-pedantic", -- 严格遵循标准
  103. -- 基础与强化告警
  104. "-Wall", -- 常用告警集合
  105. "-Wextra", -- 额外告警
  106. "-Wconversion", -- 隐式类型转换
  107. "-Wsign-conversion", -- 有/无符号转换
  108. "-Wdouble-promotion", -- float 隐式提升为 double
  109. "-Wstrict-prototypes", -- 函数声明原型检查
  110. "-Wold-style-definition", -- 旧式函数定义检查
  111. "-Wimplicit-fallthrough", -- switch 穿透检查
  112. "-Wshadow", -- 变量遮蔽检查
  113. "-Wcast-align", -- 潜在未对齐转换
  114. "-Wpointer-arith", -- 指针算术风险
  115. "-Warray-bounds", -- 数组越界检查
  116. "-Wshift-overflow", -- 位移溢出检查
  117. "-Wformat-truncation", -- 格式化截断检查
  118. "-Walloc-size", -- 分配大小异常
  119. "-Wnull-dereference", -- 空指针解引用
  120. "-Wtautological-compare", -- 恒真/恒假比较
  121. "-Wstrict-overflow", -- 有符号溢出假设
  122. "-Wmissing-prototypes", -- 缺少原型声明
  123. "-Wmissing-declarations", -- 缺少对外声明
  124. "-Wredundant-decls", -- 冗余声明
  125. "-Wunreachable-code", -- 不可达代码
  126. "-Wtype-limits", -- 类型边界恒真比较
  127. "-Wshift-negative-value", -- 负值位移检查
  128. "-Wdiv-by-zero", -- 除零检查
  129. "-Wformat-security", -- 格式化安全检查
  130. "-Wdisabled-optimization",-- 被禁用优化提示
  131. "-Wreturn-local-addr", -- 返回局部地址检查
  132. "-Wdeprecated", -- 弃用 API 提示
  133. "-Wuninitialized", -- 未初始化变量检查
  134. -- 代码生成与安全策略
  135. "-fstack-protector-strong", -- 强栈保护
  136. "-Wmissing-include-dirs", -- 头文件目录缺失
  137. "-Wcast-qual", -- 丢失 const/volatile 限定
  138. "-Wconditional-uninitialized", -- 条件分支未初始化
  139. "-Wcovered-switch-default", -- switch default 覆盖提示
  140. "-Wformat-nonliteral", -- 非字面量格式串
  141. "-Wformat-signedness", -- 格式化符号位不匹配
  142. "-Wvla", -- 可变长数组检查
  143. "-fno-common", -- 禁止旧式多重定义
  144. "-fno-strict-aliasing", -- 放宽别名优化,减少 UB 风险
  145. "-Wdocumentation", -- 文档注释检查
  146. "-Wparentheses-equality", -- 可疑括号比较
  147. -- 针对当前仓库的降噪项(避免第三方/历史代码噪声淹没关键告警)
  148. "-Wno-documentation",
  149. "-Wno-extra-semi-stmt",
  150. "-Wno-unsafe-buffer-usage",
  151. "-Wno-declaration-after-statement",
  152. "-Wno-padded",
  153. "-Wno-switch-default",
  154. "-Wno-unused-macros",
  155. {force = true}
  156. )
  157. -- 头文件
  158. add_includedirs(project_path("./RyanJson"), {public = true})
  159. add_includedirs(project_path("./example"), {public = true})
  160. add_includedirs(project_path("./test/fuzzer/include"), {public = true})
  161. add_includedirs(project_path("./test/unityTest/runner"), {public = true})
  162. add_includedirs(project_path("./test/unityTest/common"), {public = true})
  163. add_includedirs(project_path("./test/unityTest/include"), {public = true})
  164. add_includedirs(project_path("./test/unityTest/cases/core"), {public = true})
  165. add_includedirs(project_path("./test/unityTest/cases/scenario"), {public = true})
  166. add_includedirs(project_path("./test/unityTest/cases/usage"), {public = true})
  167. add_includedirs(project_path("./test/unityTest/cases/edge"), {public = true})
  168. add_includedirs(project_path("./test/unityTest/cases/stability"), {public = true})
  169. add_includedirs(project_path("./test/unityTest/cases/equality"), {public = true})
  170. add_includedirs(project_path("./test/unityTest/cases/utils"), {public = true})
  171. add_includedirs(project_path("./test/externalModule/valloc"), {public = true})
  172. add_includedirs(project_path("./test/externalModule/tlsf"), {public = true})
  173. add_includedirs(project_path("./test/externalModule/cJSON"), {public = true})
  174. add_includedirs(project_path("./test/externalModule/unity/src"), {public = true})
  175. add_includedirs(project_path("./test/unityTest/cases/RFC8259"), {public = true})
  176. -- 头文件仍由主目标暴露,源码改为依赖静态库 yyjsonStatic
  177. add_includedirs(project_path("./test/externalModule/yyjson"), {public = true})
  178. -- 依赖第三方静态库(减少重复编译)
  179. add_deps("yyjsonStatic")
  180. add_includedirs(project_path("./test/externalModule/FreeRTOS-Kernel/include"), {public = true})
  181. add_includedirs(project_path("./test/externalModule/FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix"), {public = true})
  182. -- 源文件
  183. add_files(project_path("./RyanJson/*.c"), {public = true})
  184. add_files(project_path("./example/*.c"), {public = true})
  185. add_files(project_path("./test/unityTest/**.c"), {public = true}, {cxflags = "-w"})
  186. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/list.c"), {public = true}, {cxflags = "-w"})
  187. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/queue.c"), {public = true}, {cxflags = "-w"})
  188. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/tasks.c"), {public = true}, {cxflags = "-w"})
  189. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/timers.c"), {public = true}, {cxflags = "-w"})
  190. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/event_groups.c"), {public = true}, {cxflags = "-w"})
  191. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/stream_buffer.c"), {public = true}, {cxflags = "-w"})
  192. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/port.c"),
  193. {public = true},
  194. {cxflags = "-w"})
  195. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c"),
  196. {public = true},
  197. {cxflags = "-w"})
  198. add_files(project_path("./test/externalModule/FreeRTOS-Kernel/portable/MemMang/heap_4.c"), {public = true}, {cxflags = "-w"})
  199. add_files(project_path("./test/externalModule/valloc/*.c"), {public = true}, {cxflags = "-w"})
  200. add_files(project_path("./test/externalModule/tlsf/*.c"), {public = true}, {cxflags = "-w"})
  201. add_files(project_path("./test/externalModule/cJSON/*.c"), {public = true}, {cxflags = "-w"})
  202. add_files(project_path("./test/externalModule/unity/src/*.c"), {public = true}, {cxflags = "-w"})
  203. if isFuzz then
  204. -- fuzz 目标:编入全部 fuzz case
  205. add_files(project_path("./test/fuzzer/**.c"), {public = true})
  206. else
  207. -- unit 目标:仅补最小 fuzzer runtime 依赖,避免注入 libFuzzer main。
  208. -- 原因:RyanJsonPrint.c 在 RyanJsonLinuxTestEnv 下会引用 RyanJsonFuzzerShouldFail。
  209. add_files(project_path("./test/fuzzer/utils/fuzzerDriver.c"), {public = true}, {cxflags = "-w"})
  210. add_files(project_path("./test/fuzzer/utils/fuzzerMemory.c"), {public = true}, {cxflags = "-w"})
  211. end
  212. end
  213. target("RyanJson", function()
  214. -- 默认目标:Unit 测试路径(不注入 libFuzzer main)
  215. setupRyanJsonTarget(false)
  216. end)
  217. target("RyanJsonFuzz", function()
  218. -- 专用 fuzz 目标:默认不参与普通 xmake 构建
  219. set_default(false)
  220. setupRyanJsonTarget(true)
  221. end)