arm_gcc: help ld link all these libs together

There is some confusion as to what the following flags do:

--start-group/--end-group
--[no-]whole-archive

Before explaining them further, the following facts should be
highlighted:

Fact: the linker loads *all* input *.o objects
Fact: a static library is an archive of object files
Fact: the linker will try to resolve symbols across *all* currently
	loaded object
Fact: if a symbol cannot be resolved among currently loaded object, the
	linker will consider static libraries in the order provided and
	load the first object that provides that symbol
Fact: the linker only considers static libraries once and in the order
	provided

--start-group/--end-group pairs tell the linker to re-attempt
considering the libraries contained within the pair, and *in the order
provded* for as long as new unresolved symbols can be resolved that way.

--whole-archive/--no-whole-archive pairs tell the linker to load all
objects from the libraries contained within the pair, making it
equivalent to manually extracting all the object files out of these
libraries and providing them on the command line to the linker

In well-formed cases, none of these flags are necessary. An acyclic
chain of depencies can be established within these libraries by making
them into source_set() targets that depend on each other. In this case,
gn will output the correct order for these libraries.

There are cases where this is not possible. This is typically the case
when vendor-provided libraries have circular dependencies among them.
In these cases, either --start-group/--end-group or
--whole-archive/--no-whole-archive pairs need to be used.

--whole-archive/--no-whole-archive is safer because it allows the proper
resolution of weak/strong symbols.
Example:
libfoo.a:
  foo.o:
    w foo

libbar.a:
  bar.o:
    T foo

main.o:
  U foo

$ gcc main.o libfoo.a libbar.a

will result in the weak symbol defined in libfoo.a to be used.

$ gcc main.o --Wl,--whole-archive libfoo.a libbar.a -wl,--no-whole-archive

will result in the strong symbol defined in libbar.a to be used.

In light of all of the above, we propose always using
--whole-archive/--no-whole-archive and relying on --gc-sections to trim
the resulting executable to a reasonable size.

Change-Id: I355200961b6df6e797f3035f7945eb1a7f9e30b7
1 file changed
tree: bd25f68e35b2c7bd5e9da95ad6f39706bbba8c87
  1. docs/
  2. env_setup/
  3. pw_bloat/
  4. pw_build/
  5. pw_cli/
  6. pw_cpu_exception/
  7. pw_cpu_exception_armv7m/
  8. pw_docgen/
  9. pw_dumb_io/
  10. pw_dumb_io_baremetal_stm32f429/
  11. pw_dumb_io_stdio/
  12. pw_module/
  13. pw_preprocessor/
  14. pw_presubmit/
  15. pw_protobuf_compiler/
  16. pw_span/
  17. pw_status/
  18. pw_string/
  19. pw_test_server/
  20. pw_toolchain/
  21. pw_unit_test/
  22. pw_varint/
  23. targets/
  24. .clang-format
  25. .gitignore
  26. .gn
  27. .pylintrc
  28. AUTHORS
  29. BUILD
  30. BUILD.gn
  31. BUILDCONFIG.gn
  32. CONTRIBUTING.md
  33. LICENSE
  34. modules.gni
  35. pw_vars_default.gni
  36. README.md
  37. WORKSPACE
README.md

Pigweed Embedded Oriented Software Libraries

Pigweed is a collection of embedded-focused libraries, which we call “modules”. These modules are designed for small-footprint MMU-less microcontrollers like the ST Micro STM32L452 or the Nordic NRF82832. The modules are designed to facilitate easy integration into existing codebases.

Pigweed is in the early stages of development.

Getting Started

$ git clone sso://pigweed.googlesource.com/pigweed/pigweed ~/pigweed
$ cd ~/pigweed
$ env_setup/cipd/cipd.py auth-login  # Once per machine.
$ . env_setup/setup.sh

If you‘re using Homebrew and you get an error saying module 'http.client' has no attribute 'HTTPSConnection' then your Homebrew Python was not set up to support SSL. Ensure it’s installed with brew install openssl and then run brew uninstall python && brew install python. After that things should work.

The environment setup script will pull down the versions of tools necessary to build Pigweed and add them to your environment. You can then build with either GN or Bazel. You can also confirm you're getting the right versions of tools—they should be installed under env_setup/.

$ which gn
~/pigweed/env_setup/cipd/tools/gn
$ gn gen out/host
$ ninja -C out/host
$ which bazel
~/pigweed/env_setup/cipd/tools/bazel
$ bazel test //...

And do the following to test on the STM32F429 Discovery board. (The bazel build does not yet support building for hardware.)

$ gn gen --args='pw_target_config = "//targets/stm32f429i-disc1/target_config.gni"' out/disco
$ ninja -C out/disco
$ pw test --root out/disco/ --runner stm32f429i_disc1_unit_test_runner -- --port /dev/ttyACM0

If any of this doesn't work please file a bug.