set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_SKIP_RPATH TRUE)
get_ABI_option_value()
# 通用编译选项
set(_COMMON_FLAGS_LIST
-ggdb # 生成 GDB 调试信息
-pipe # 加快编译,使用管道而非临时文件
-fstack-protector-strong # 强化栈保护,检测栈溢出
-fPIE # 生成位置无关代码(可执行文件 ASLR 必需)
-fno-common # 禁止多重定义的全局变量被合并,避免弱符号问题
-D_FORTIFY_SOURCE=2 # glibc 编译期/运行时安全检查(格式化、缓冲区)
-Wall # 常规警告
-Wextra # 更多额外警告
-Wfloat-equal # 浮点比较警告
-Wformat # 检查 printf/scanf 格式化问题
-Wformat-security # 禁止不安全的格式化字符串
-Wstack-protector # 确保栈保护启用
-Wl,-z,relro # 链接器:启用 RELRO,部分 GOT 只读
-Wl,-z,now # 链接器:程序启动即绑定符号(Full RELRO)
-Wl,-z,noexecstack # 链接器:禁止可执行栈
-Wl,--as-needed # 链接器:仅加载真正需要的库,减少攻击面
)
# C 语言特有选项
set(_C_FLAGS_LIST
-Wimplicit-function-declaration # 禁止使用未声明的函数
-Wmissing-prototypes # 要求函数在头文件声明
-Wstrict-prototypes # C 函数参数必须显式类型(不允许隐式 int)
-Wold-style-definition # 禁止 K&R 风格函数定义
-Wshadow # 警告变量名遮蔽(容易出现逻辑错误)
-Wpointer-arith # 不安全的指针算术警告
)
# C++ 特有选项
set(_CXX_FLAGS_LIST
-fexceptions # 启用 C++ 异常(大多数项目都需要)
-Wnon-virtual-dtor # 基类没有虚析构时警告(防止内存泄露)
-Wdelete-non-virtual-dtor # 删除非虚析构基类指针导致 UB 时警告
-Woverloaded-virtual # 检测覆盖隐藏基类虚函数
-Wzero-as-null-pointer-constant # 禁止用 0/NULL 代替 nullptr
-Wold-style-cast # 禁止 C 风格强制类型转换
-Wduplicated-cond # 重复条件检测(逻辑 bug)
-Wduplicated-branches # if/else 分支冗余检测
)
list(JOIN _COMMON_FLAGS_LIST " " _COMMON_FLAGS)
list(JOIN _C_FLAGS_LIST " " _C_FLAGS)
list(JOIN _CXX_FLAGS_LIST " " _CXX_FLAGS)
# 应用全局 C / C++ 编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_COMMON_FLAGS} ${_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_COMMON_FLAGS} ${_CXX_FLAGS}")
if(USE_CXX11_ABI)
add_definitions(-U_GLIBCXX_USE_CXX11_ABI -D_GLIBCXX_USE_CXX11_ABI=1)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
endif()
# 链接器选项
set(_LD_FLAGS_GLOBAL_LIST
-rdynamic # 保留符号(调试/插件系统需要)
-ldl # 显式链接 libdl(dlopen/dlsym)
-Wl,-z,relro # RELRO(只读 GOT)
-Wl,-z,now # Full RELRO(立即绑定)
-Wl,-z,noexecstack # 栈不可执行
-Wl,--as-needed # 只加载需要的库
)
list(JOIN _LD_FLAGS_GLOBAL_LIST " " LD_FLAGS_GLOBAL)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LD_FLAGS_GLOBAL}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_FLAGS_GLOBAL} -pie") # 可执行文件启用 PIE
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g2")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR "$ENV{MINDIE_ENABLE_PROF}" MATCHES "^1$")
add_definitions(-DENABLE_PROF) # 向代码注入宏 ENABLE_PROF
endif()
if(USE_FUZZ_TEST OR DOMAIN_LAYERED_TEST)
enable_testing()
add_compile_definitions(UT_ENABLED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
if(USE_FUZZ_TEST)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-coverage=trace-pc") # fuzz 用代码覆盖
add_definitions(-DFUZZ_TEST)
endif()
# 第三方编译选项
set(THIRD_PARTY_C_FLAGS
-fstack-protector-strong
-D_FORTIFY_SOURCE=2
-O2
-ftrapv
-Wl,-z,relro
-Wl,-z,now
-s
)
get_architecture(ARCH)
if(${ARCH} STREQUAL "aarch64")
list(APPEND THIRD_PARTY_C_FLAGS "-march=armv8-a+crc")
endif()
set(THIRD_PARTY_CXX_FLAGS ${THIRD_PARTY_C_FLAGS})
list(APPEND THIRD_PARTY_CXX_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=${USE_CXX11_ABI}")