How is the AOSP project built?

You have already found out a lot, and you are right with the link from m to soong_ui.bash and then starting microfactory.

From my reading of the code, the purpose of soong_build_go is to build the package android/soong/cmd/soong_ui, with the binary name soong_ui. Like Yong said in the other answer, this creates the binary soong_ui under the directory $(getoutdir), and the source for that binary is located at build/soong/cmd/soong_ui/main.go.

As for your updated question about an Android.bp file, it is symlinked from build/soong/root.bp when repo sync is run, but as you can see, the file is empty.

Instead, in m it tells Soong to build all_modules, which eventually runs another tool called kati. From the description in, Kati processes GNU makefiles and turns them into Ninja build files.

At this point we can (mostly) assume regular Make semantics, even though the underlying build system is actually Kati and Ninja and Soong etc. Since the working directory is $TOP, the Makefile at the root directory, which is symlinked from build/make/core/ is used. Which includes which then includes build/make/core/Makefile. Inside that makefile you can see how the different .img files are built (e.g. system.img).

Let's take make systemimage as an example:

The call sequence is:

  1. prebuilts/build-tools/linux-x86/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode "systemimage". And $(getoutdir)/soong_ui is build by "build_go soong_ui android/soong/cmd/soong_ui"
  2. build/soong/cmd/soong_ui/main.go#main()
  3. soong/ui/build/build.go#Build()