The short answer is that you’d expect `lib` to be built (or rather, installed) if there’s a library to install, and `include` if there are headers to install. Usually the two go together (at least for C and C++ libraries).

In `binutils`’ case, the libraries and associated headers are `libbfd` and `libopcodes`, as you mention. `libbfd` is a library used to manipulate object files in a variety of formats, `libopcodes` is a library used to map opcodes to instructions. `libbfd` is installed by default for same-host compilation, but not for cross-compilation, which is why you’re seeing different behaviour in your scenarios. You can see the conditional default in [`bfd/acinclude.m4`][1] in the source code. Both libraries should be built in all cases.

You only need `libbfd` if you want to build GDB. If you do want to install it in a cross-compilation scenario, you can tell `./configure` to do so with the `--enable-install-libbfd` option; when you do this, the libraries and header files [will be installed][2] in the appropriate host- *and* target-specific directory (`libbfd` is built for the host but contains target-specific code).