为了简化描述,下文提到目标时,如无特殊说明,均指代目标可执行文件或者目标动态库。
操作步骤如下:
选型时,在同等功能时,尽量选择代码量少、占用空间小的开源的软件。
控制C++特性的使用,如无必要,则不使用C++的高级特性。
屏蔽RTTI特性,增加编译选项-fno-rtti。
屏蔽异常我,增加编译选项-fno-exceptions。
对性能影响不大时,避免使用C++的inline特性。
增加编译选项-fno-inline。
在不影响使用时,控制对STL的组件的使用。
避免使用STL的iostream的相关模板类。
构建目标动态库时,控制符号的可见性。
增加编译选项-fvisibility=hidden。
增加编译选项-fvisibility-inlines-hidden。
定义符号导出宏,如下代码。
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define MY_EXPORT __attribute__((visibility("default")))
#define MY_IMPORT __attribute__((visibility("default")))
#else
#define MY_EXPORT
#define MY_IMPORT
#endif
// 在外部可见的符号上,使用上述宏修饰。
MY_EXPORT int foo(int a, int b);
对目标以及全部依赖,使用gc-sections特性。即:
编译源码时,增加选项-ffunction-sections -fdata-sections。
链接目标时,增加选项-Wl,--gc-sections。
链接目标时,增加选项-Wl,--icf=safe。
对目标以及全部依赖,使用LTO特性。
编译源码时,增加选项-flto=full。
链接目标时,增加选项-flto=full。
构建目标时的外部依赖,均使用静态链接。比如:
静态链接STL库。
静态链接使用前述要求编译的依赖库。
构建目标时,要求编译器对目标占用的空间进行优化。
增加选项-Os。
假如链接失败,则修改为-O2。
链接时,对于Release版本,删除不必要的调试符号。
增加选项-s。
如下使用CMake的请求,描述选项。
# 关闭C++特性
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-inline")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
# 控制符号的可见性
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fvisibility-inlines-hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden")
# 删除调试符号
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
# 开启空间优化
if (APPLE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Oz")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Oz")
else ()
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os")
endif ()
# 使用gc-section优化
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
# 使用icf优化
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--icf=safe")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--icf=safe")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--icf=safe")
# 使用LTO
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto=full")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto=full")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -flto=full")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto=full")
参考资料