Project References
Project References, as their name implies, refer not to a pre-compiled binary to be referenced, but to another project on the local disk that, when compiled, will produce an output that can be referenced.
The referenced project may or may not be part of the same Solution as the project referencing it, and in many cases, EBuild can resolve references to projects that are not part of the solution just fine, assuming all paths are correct and the project was compiled successfully, before.
Project references can be used for traditional "library" projects, but can also bring different (compatible) project types together – for example a Java-based Android app can reference an Android NDK extension project, or an iOS project may reference Extensions or a watchOS app.
How EBuild Resolves Project References
EBuild applies sophisticated logic to try its very best to resolve project references in almost every case.
Firstly, before starting the build, EBuild will check all projects in the current solution for project references. Each project reference is matched against the other projects in the solution, and if a matching project is found, it is connected to the project reference, and marked to be built before the project(s) that reference it.
If a referenced project cannot be found in the solution, EBuild will try to locate the project file on disk using either its name or its ProjectFile
meta data value. If found, the project is loaded into the solution implicitly and connected to the project reference, but marked as not Enabled
(i.e. it will not be built).
If the referenced project cannot be found either, EBuild checks if the Hintpath
of the reference is valid.
If none of these steps are successful, the build will fail.
EBuild will then determine the best build order for all projects, based on the dependencies. If a circular dependency is detected, the build will fail, otherwise EBuild will start to build each project in the order it has decided.
As each project hits the ElementsResolveReferences
task, project references are resolved using the following steps:
If a live project was connected to the project reference
If a live project was connected to the project reference in the previous steps (either because it was part of the solution, or could be located on disk), that project is used to fill the reference:
- If the project was built successfully, its output (via the
FinlOutoutForReferencing-|
collection) will be used to fulfill the reference. - If the referenced project is
Enabled
but was not built yet, that means a circular dependency was detected, and the referencing project will fail to build. - If the referenced project failed to built earlier, the referencing project will also fail to build.
- If the project is not
Enabled
(either explicitly by the user, or because it was pulled into the solution implicitly as described above), EBuild will try to locate the project'sFinalOutput.xml
file in the Cache from a previous build. If found, the data from that file (theFinlOutoutForReferencing-|
collection) will be used to fulfill the reference. - If the previous step failed, EBuild will fall back to using the
HintPath
, if valid, to fulfill the reference, and otherwise fail the build.
If no live project was connected
Otherwise, EBuild will fall back to simply looking at the HintPath
. If valid, it will be used to fulfill the project reference, otherwise the build will fail.
Covered Scenarios
The steps above cover just about any valid scenario for project References:
- Both projects are in the solution and
Enabled
. - Both projects are in the solution, the referenced project is not
Enabled
, but was built earlier. - The referenced project is not in the solution, but can be located on disk and was built earlier.
- The referenced project cannot be located, but the
HintPath
is valid.
By default, EBuild will not try to build referenced projects that are not in the solution, so if such projects have not been compiled previously, the built will fail. By passing the --build-missing-projects
, switch you can tell EBuild to treat all project references as if they were in fact listed in the solution, and build them, recursively, if needed.
Project References when Hosting EBuild in MSBuild
When building with EBuild inside Visual Studio, EBuild does not see the whole solution, but instead builds each project individually (wrapped in an MSBuild project task). EBuild will rely on option 3 and 4 from above to resolve project references in that case.
The same is true when building an individual project file without .sln
from the command line.