`gcc -march=native` work incorrectly in devshell

gcc -march=native does not enable __AVX2__ and __SSE__ inside devshell.

When I run gcc -march=native -dM -E - </dev/null | grep AVX outside devshell, it outputs:

#define __AVX__ 1
#define __AVX2__ 1

However when I run nix develop and then run gcc -march=native -dM -E - </dev/null | grep AVX again, it outputs nothing.

__AES__ is the same.

my devshell flake.nix:

{
  description = "C/C++ development environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, ... }@inputs: inputs.utils.lib.eachSystem [
    "x86_64-linux"
    "i686-linux"
    "aarch64-linux"
    "x86_64-darwin"
  ]
    (system:
      let
        pkgs = import nixpkgs {
          inherit system;
        };
      in
      {
        devShells.default = pkgs.mkShell {
          packages = with pkgs; [
            autoconf
            automake
            pkg-config
            cmake
            bear
            clang-tools_16
          ];
        };
      });
}

Now I am building a c++ project that needs AVX and AES, so this is very important for me.

gcc wrapper from nixpkgs tries to guard you against impurity (dependence on the build server CPU) imposed by -march=native:

$ cat `which gcc` | grep -C10 native
...
if [ "$NIX_ENFORCE_NO_NATIVE_x86_64_unknown_linux_gnu" = 1 ]; then
    kept=()
    # Old bash empty array hack
    for p in ${params+"${params[@]}"}; do
        if [[ "$p" = -m*=native ]]; then
            skip "$p"
        else
            kept+=("$p")
        fi
    done
    # Old bash empty array hack
    params=(${kept+"${kept[@]}"})
fi

If you still want the impurity you can disable it:

$ export NIX_ENFORCE_NO_NATIVE=0
$ gcc -march=native -dM -E - </dev/null | grep AVX
#define __AVX__ 1
#define __AVX2__ 1

Otherwise it might be better to explicitly set -march= or -mavx2 via NIX_CFLAGS_COMPILE as part of a package you need.

Thank you very much!