使用GCC≥12编译GCC时libcpp因格式安全警告构建失败
用GCC ≥12编译GCC时触发
-Werror=format-security错误的排查与解决 尝试用版本≥12的GCC编译GCC源码,执行make时出现多个格式安全相关的错误,报错代码经git blame确认自2012年未修改,怀疑是构建配置遗漏。当前在Nix Shell环境下构建,相关信息如下:
错误日志
tti -I../../../../gittea/gcc/libcpp -I. -I../../../../gittea/gcc/libcpp/../include -I../../../../gittea/gcc/libcpp/include -c -o expr.o -MT expr.o -MMD -MP -MF .deps/expr.Tpo ../../../../gittea/gcc/libcpp/expr.cc ../../../../gittea/gcc/libcpp/expr.cc: In function ‘unsigned int cpp_classify_number(cpp_reader*, const cpp_token*, const char**, location_t)’: ../../../../gittea/gcc/libcpp/expr.cc:842:35: error: format not a string literal and no format arguments [-Werror=format-security] 842 | cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location, | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 843 | 0, message); | ~~~~~~~~~~~ ../../../../gittea/gcc/libcpp/expr.cc:845:38: error: format not a string literal and no format arguments [-Werror=format-security] 845 | cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ 846 | virtual_location, 0, message); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../../../gittea/gcc/libcpp/expr.cc:855:33: error: format not a string literal and no format arguments [-Werror=format-security] 855 | cpp_warning_with_line (pfile, CPP_W_SIZE_T_LITERALS, | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 856 | virtual_location, 0, message); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../../../gittea/gcc/libcpp/expr.cc:867:42: error: format not a string literal and no format arguments [-Werror=format-security] 867 | cpp_pedwarning_with_line (pfile, CPP_W_C11_C2X_COMPAT, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 868 | virtual_location, 0, message); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../../../gittea/gcc/libcpp/expr.cc:870:39: error: format not a string literal and no format arguments [-Werror=format-security] 870 | cpp_warning_with_line (pfile, CPP_W_C11_C2X_COMPAT, | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 871 | virtual_location, 0, message); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../../../gittea/gcc/libcpp/expr.cc:877:35: error: format not a string literal and no format arguments [-Werror=format-security] 877 | cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 | message); | ~~~~~~~~ cc1plus: some warnings are being treated as errors
当前Nix Flake配置
{ description = "gcc compiler"; inputs = { nixpkgs.url = "github:nixos/nixpkgs"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; in { packages = { default = pkgs.gnumake; }; formatter = pkgs.nixpkgs-fmt; devShell = pkgs.mkShell { buildInputs = [ pkgs.gnumake pkgs.gcc13 pkgs.libgcc pkgs.glibc pkgs.gmp pkgs.libmpc pkgs.mpfr pkgs.flex pkgs.bison pkgs.isl pkgs.pkg-config pkgs.autoconf-archive pkgs.autoconf pkgs.automake ]; }; } ); }
解决步骤
1. 调整GCC构建配置参数
高版本GCC默认开启-Wformat-security并将其转为错误,可在configure阶段禁用该规则的错误转换:
../configure --disable-werror=format-security
若需临时禁用所有警告转错误(不推荐,可能掩盖其他问题):
../configure --disable-werror
2. 修改Nix Shell环境变量
在Nix Shell的mkShell中显式覆盖编译参数,禁用该错误:
devShell = pkgs.mkShell { buildInputs = [ # 保留原有依赖 pkgs.gnumake pkgs.gcc13 pkgs.libgcc pkgs.glibc pkgs.gmp pkgs.libmpc pkgs.mpfr pkgs.flex pkgs.bison pkgs.isl pkgs.pkg-config pkgs.autoconf-archive pkgs.autoconf pkgs.automake ]; # 禁用format-security的错误转换 CFLAGS = "-Wno-error=format-security"; CXXFLAGS = "-Wno-error=format-security"; };
3. 更换编译用的GCC版本
GCC官方推荐用比目标版本低一级的编译器编译自身,比如编译GCC 13时用GCC 12。可在Nix配置中将pkgs.gcc13替换为pkgs.gcc12,降低编译工具链版本以兼容旧代码。
4. 切换GCC源码分支
若编译的是未适配新警告规则的旧GCC分支,可切换到对应稳定分支(如gcc-13-branch),该分支代码已适配高版本编译器的警告规则。
内容的提问来源于stack exchange,提问作者vincenzopalazzo
相关产品推荐
相关产品推荐

