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).
binutils’ case, the libraries and associated headers are
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 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 in the appropriate host- and target-specific directory (
libbfd is built for the host but contains target-specific code).