在尝试在 NixOS (16.09) 上构建 GCC (6.3) 时,nix-shell
我得到了以下信息:
make[1]: Entering directory '<my-build-path>/coreboot/util/crossgcc/build-i386-elf-GCC/build-x86_64-pc-linux-gnu/libcpp'
test -f config.h || (rm -f stamp-h1 && make stamp-h1)
g++ -I../../../gcc-6.3.0/libcpp -I. -I../../../gcc-6.3.0/libcpp/../include -I../../../gcc-6.3.0/libcpp/include -O2 -fomit-frame-pointer -m64 -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long -fno-exceptions -fno-rtti -I../../../gcc-6.3.0/libcpp -I. -I../../../gcc-6.3.0/libcpp/../include -I../../../gcc-6.3.0/libcpp/include -c -o expr.o -MT expr.o -MMD -MP -MF .deps/expr.Tpo ../../../gcc-6.3.0/libcpp/expr.c
../../../gcc-6.3.0/libcpp/expr.c: In function 'unsigned int cpp_classify_number(cpp_reader*, const cpp_token*, const char**, source_location)':
../../../gcc-6.3.0/libcpp/expr.c:686:18: error: format not a string literal and no format arguments [-Werror=format-security]
0, message);
^
../../../gcc-6.3.0/libcpp/expr.c:689:39: error: format not a string literal and no format arguments [-Werror=format-security]
virtual_location, 0, message);
^
cc1plus: some warnings being treated as errors
make[1]: *** [Makefile:224: expr.o] Error 1
make[1]: Leaving directory '<my-build-path>/coreboot/util/crossgcc/build-i386-elf-GCC/build-x86_64-pc-linux-gnu/libcpp'
make: *** [Makefile:2730: all-build-libcpp] Error 2
sh ../gcc-6.3.0/mkinstalldirs <my-build-path>/coreboot/util/crossgcc/xgcc <my-build-path>/coreboot/util/crossgcc/xgcc
sh: line 3: cd: i386-elf/libgcc: No such file or directory
make: *** [Makefile:10462: install-target-libgcc] Error 1
哪里-Werror=format-security
似乎是失败的原因(尽管我在命令中没有看到这个确切的选项)。然而<nixpkgs>/pkgs/development/compilers/gcc/6/default.nix
我发现这个:
hardeningDisable = [ "format" ];
并且猜测失败可能是由于NixOS的安全加固措施造成的,其中有一些有禁用以编译 GCC(假设 GCC 开发人员知道他们在这些函数中做什么)。用 GCC 6.2 和 5.4 进行了测试——同样的事情。
所以问题是如何禁用环境format
的强化选项(特别是)nix-shell
?或者那些“被视为错误的警告”从何而来?
选项描述:
- https://nixos.org/nixpkgs/manual/#sec-hardening-in-nixpkgs
- https://blog.mayflower.de/5800-Hardening-Compiler-Flags-for-NixOS.html
根据这个答案
nix-shell
与 Nix 表达式无关...但是当我make
用NIX_DEBUG
标志调用时,
env NIX_DEBUG=' ' make crossgcc-i386
我得到的输出<nixpkgs>/pkgs/build-support/cc-wrapper/add-hardening.sh
,例如HARDENING: enabling format
;据我推断,当我make
调用nix-shell
.
也许我只是需要通过 碰撞一些东西nixos-option
,但到底是哪个选项?我不能只是grep
这样...(没有dconf dump /
or的类似物gsettings list-recursively
)
答案1
警告format-security
有被禁用,或者至少不被-Werror
禁用,因为:
强化选项是由编译器包装器强加的,这就是它们不显示在日志中的原因。
显然hardeningDisable
这是影响包装器的唯一方法。
一种可能的解决方案是创建一个与 一起使用的虚拟 Nix 表达式nix-shell -A
。例如:
复制~/.nix-defexpr/channels_root/nixos/
到一个单独的地方(<nixpkgs'>
)并使其可写,
添加<nixpkgs'>/pkgs/tools/misc/coreboot/default.nix
包含
{ stdenv, gcc6, flex, bison, ncurses, iasl, doxygen, zlib, isl, python }:
stdenv.mkDerivation {
name = "coreboot";
buildInputs = [ gcc6 flex bison ncurses iasl doxygen zlib isl python ];
hardeningDisable = [ "format" ]; # to build the cross-compiler
}
<nixpkgs'>/top-level/all-packages.nix
并像往常一样注册它
,最后调用nix-shell <nixpkgs'> -A coreboot
创建所需的环境。
不过我认为它应该更容易(适用于nix-shell -p
)。
答案2
在 nix-shell 中禁用 gcc 强化标志
# shell.nix
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
mkShell {
# disable all hardening flags
NIX_HARDENING_ENABLE = "";
# enable default hardening flags
#NIX_HARDENING_ENABLE = "pie pic format stackprotector fortify strictoverflow";
buildInputs = [
#gnumake
#python3
# ...
];
}
核实
$ NIX_DEBUG=1 gcc -v 2>&1 | grep ^HARDENING
HARDENING: disabled flags: pie pic format stackprotector fortify strictoverflow
基于
$ which gcc
/nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/bin/gcc
$ grep add-hardening.sh /nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/bin/gcc
source /nix/store/l0fvy72hpfdpjjs3dk4112f57x7r3dlm-gcc-wrapper-12.2.0/nix-support/add-hardening.sh
也可以看看:Nixpkgs 中的强化在 nixpkgs 手册中