This issue describes the plans to migrate compile info from ObjcProvider to CcCompilationContext.  It will focus on the main migration step, which moves the compilation info in ObjcProvider into an embedded CcCompilationContext.  Note this step is Starlark API compatible (except for one secondary feature).  The issue will also describe any expected changes in behavior and the followup cleanup work.
What is being migrated:
What is not being migrated:
Initial rollout is Starlark API compatible, except for the strict dependency propagation feature. Later cleanups may break compatibility.
ObjcProviderThe migration will make the following changes to ObjcProvider:
CcCompilationContext, instead of directly as items in ObjcProvider.  The items for those fields in ObjcProvider will become empty.objc_proto_library includes (which is only used within Google), and that will be moved to a special field in ObjcProvider.ObjcProvider.  Instead, to get the strict dependency behavior, a rule should fetch that information directly from its dependencies.  For an example of how to do this, see swift_library which is already set up this way.ObjcProvider Starlark API will have a new accessor field (compilation_context) to access its CcCompilationContext.  This field is a temporary measure to ease migration, and will be deleted once all the cleanup tasks are completed.The migration will make the following changes the native rules:
Previously, objc_library exports a CcInfo with an incomplete CcCompilationContext that only has header information.  Now it will export the complete CcCompilationContext, identical to the one embedded in its ObjcProvider.
Note this change can expose bugs/issues in rules that depend on objc_library and consume its CcInfo.
Rules that produce final library or executable artifacts (e.g. apple_binary, apple_static_libary) generate ObjcProviders for linking.  These ObjcProviders will no longer carry compilation information.
srcs attribute) of objc_library are now propagated to dependencies.  This behavior makes objc_library more consistent with that for cc_library.This section describes the changes made to the blaze internals for the migration. It is mainly of interest to code reviewers, or those who are interested in the inner workings of Objective C/C++ rules. It may be skipped by most users.
ObjcProviderObjcProvider is used not only for information exchange between rules, it is used internally as well.  The migration covers these uses.  There are three issues in migrating them:
objc_library's compile action depends on its own provider.
Currently, a compilation rule such as objc_library generates its ObjcProvider, then uses it to generate its compile action.  This flow is problematic for the migration, because the compile action generates a CcCompilationContext that we want to use to create the ObjcProvider -- so the migration would cause a circular dependency in this flow.
The migration requires breaking this circular dependency.  A compilation rule is modified so that it collects all the compilation info into a new object called ObjcCompilationContext, which serves as a substitute for the way ObjcProvider was used before in its own compilation.  Whereas ObjcCommon used to create an ObjcProvider up front, it now creates an ObjcCompilationContext and an ObjcProvider.Builder, the latter of which only contains non-compile information.  The creation of the final ObjcProvider is postponed until CompilationSupport.compile() is called.
Distinguish between two kinds of uses of ObjcCommon.
Because of the the aforementioned change, it is useful to distinguish between two use cases of ObjcCommon: those that are used to create compilation actions and those that are not.
ObjcCommon used to create compilation actions needs to export an ObjcProvider.Builder, and rely on CompilationSupport.compile() to create the final ObjcProvider that has the CcCompilationContext from the compile action.ObjcCommon that do not create compilation actions can export an ObjcProvider directly, as before.We define a enum ObjcCommon.Purpose, set during the creation of ObjcCommon, to distinguish the two use cases.
Implementation of strict dependency propagation
Changing objc_library so that it doesn't depend on its own provider also affects how strict dependency propagation is implemented.  Because we fetch strict dependency items directly from the dependent providers, rather than indirectly through a new provider, we no longer need to propagate those items.  This simplifies implementation and allows us to get rid of the wonky propagation mechanism altogether.
The only remaining use of strict dependency propagation is for objc proto library include paths, so we just store that in a normal field in ObjcProvider that is not propagated.
The migration to CcCompilationContext allows us to get rid of a bunch of existing hacky hooks used to get Objective-C compilation to work properly with underlying C++ infrastructure.  The following hooks are used to work around include scanning issues, which are obsoleted by the migration and can be deleted:
ObjcCppSemantics and CppCompilationAction).CompilationSupport.ccCompileAndLink().The followup work can be divided into three phases:
CcInfo / CcCompilationContext for compile info.  This info will be identical to information stored in the CcCompilationContext embedded in ObjcProvider.CcInfo for compile info.ObjcProvider.  Remove the ObjcProvider compile-info related Starlark APIs.I will migrate the native rules, apple rules, swift rules, and tulsi as described above. Users also need to migrate any Starlark rules they own that use ObjcProvider for compile information. We will provide two incompatible flags to aid the migration:
--incompatible_objc_compile_info_migration: This flag controls whether native rules will use compile info from ObjcProvider or CcInfo.  If the flag is false, bazel will get its compile info from ObjcProvider (pre-migration behavior).  If the flag is true, bazel will get its compile info from CcInfo (post-migration behavior).
Tentative time-frame: available and default false in 3.0, default true the next release (i.e. 3.1), removed the following release (i.e. 3.2).
--incompatible_objc_provider_remove_compile_info: This flag deletes the Starlark APIs to put compile info in an ObjcProvider.
Tentative time-frame: available and default false in 3.2, default true next release (i.e. 4.0), removed in the following release (i.e. 4.1).
We recommend that rules be migrated as follows:
Migrate Starlark rules that define ObjcProvider with compile info.
These are rules that insert any of the following fields into ObjcProvider:  define, framework_search_paths, header, include, include_system, iquote.  For each such rule, generate a CcInfo containing a CcCompilationContext with the same information, and add it to list of providers emitted by that rule.
There is a 1:1 correspondence between these fields and where they should land in CcCompilationContext: 
define -> definesframework_search_paths -> framework_includesheader -> headersinclude -> includesinclude_system -> system_includesiquote -> quote_includesMake sure all bazel Starlark rules you are using have been migrated up to this step (you may have to update your rules_apple, etc.).  Flip --incompatible_objc_compile_info_migration to true, which will help test whether you have migrated all your rules in step (1) properly.
Migrate Starlark rules that use compile info in ObjcProvider.  These rules should be migrated to use compile info from Ccinfo instead.  This migration may include migrating rules that propagate compile info from its deps, which can be done using cc_common.merge_cc_infos.
Migrate Starlark rules so that they stop adding compile info to ObjcProvider.
Make sure all bazel Starlark rules you are using have been migrated up to this step (you may have to update your rules_apple, etc.)  Flip --incompatible_objc_provider_remove_compile_info to true.  This will help test whether you have completed the migration.
I will attach examples of the migrations as they become available, in rules_apple/rules_swift/tulsi.
Is there a plan to also migrate link info to LinkingContext?
We do plan do the the linking migration, but no written plan yet. I'll provide more info when I have them.
@googlewalt this commit seems to have broken apple_static_framework_import when compiling ObjC without clang modules enabled. Without the framework search path being exported, the compiler doesn't know where to find the headers.
Referencing this here as there doesn't seem to be a ticket tracking this work in rules_apple
Please run bazel with --incompatible_objc_compile_info_migration.  The flag is now required in order to use the latest rules_apple and rules_swift.
Ideally, I would have enabled that flag by default so that you don't have to do anything, but there hasn't been an opportunity to do so given that a bazel major release has not happened since March, and I want to wrap up the rules migration.
@googlewalt That worked great, thanks!
Most helpful comment
Is there a plan to also migrate link info to LinkingContext?