We have a huge solution with both Oxygene and VC# projects. All targeting .NET.
We moved recently to Elements10 and because we have some projects that have post/pre build events and some projects that have Nuget packages that have multiple .targets imports we converted all over Oxygene projects to use the legacy targets.
In a previous related issue I was told that normally Ebuild projects should work just fine except for those couple of exceptions. So I started to convert some projects back to EBuild oxygene projects.
That works perfectly fine in VS2019, but when the sln is build on our build server the build fails:
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\RemObjects Software\Elements\RemObjects.Elements.targets(53,3): EBuild error : Project Reference ‘…\Common\DataModel\DataModel.oxygene’ could not be resolved for target ‘Echoes’ (Echoes .NET anycpu).
Exactly that. EBuild uses three options to resolve a project reference:
(a) if the project is in the same “solution” it’ll have all the infos. I’m putting “solution” in scare-quotes, because when hosting in MSBuild/VS thats a special scenario and each project runs EBuild standalone. Sop for your purpose, that other project is not in the same solution, as far as EBuild sees it.
(b) Next, it checks if a FinalOutput.xml file for the project exists — which will also provide all the infos EBuild needs. However, that file will only exist of the other project was built with ERBuild as well. Since your project is a legacy project, it’s not, so this option too fails.
It took me a while to figure out why option C did not work, but I found it:
We tell MSBuild to use a custom output folder; so in VS2019 the hint path is correct, but on the build server it is not existing.
I guess I revert to legacy projects for the time being…
Oh, Also, EBuild will already try and adjust for different configurations. Eg. an unsatisfied HintPath to ...\Debug\Your.dll will find the dll in ...\Release\Your.dll, assuming the last part component matches a valid configuration in your project (e.g. ...\Foo\Your.dll will not work, unless you hav a configuration called Foo).
In addition, vNext will split the <HintPath> metadata at any occurrence of a semicolon (since Elements projects use Windows paths with backslash (\) everywhere, they’ll also use the Windows path separator char (;), even on Unix) and try them each win row, so you could in theory provide two totally separate paths there, and the first that matches (including the above-mentioned adjustment for configuration) will be used.
This will work for project and regular (and NuGet) references.
In the interest of finding a long term solution for this as well (and given that EBuild will never actually process/run an actual MSBuild target), what do these .targets’ do, and what functionality would you need in EBuild in order to make using these packages feasible (if even possible)?
Having multiple hint paths would be great but because we set the output folder during builds relative to the solution file, and we have multiple solutions, this would take a lot of work to make that work.
Maybe for vNext you could fetch the output folder from MSBuild inside the wrapper code and add that to the list of hintpaths of EBuild. (maybe in the last position of the list)
I merely clarified, because I can’t tell apart where the OutputPath property cam from, if it wasn’t specified on the command line, chances are high it would be separate for each project (e.g. “.\Bin\Debug” relative to each project).
I’ll think about if it’s feasible to add this as fallback, without negative side effects. (I could imagine, say, if the output folder is different for each project, and a project reference is actually broken, it might accidentally pick up an older copy thats still left in the output folder from a previous build, rather than failing on the missing reference — and that’d be bad).
Would a separate property be feasible as a fallback, eg /property:AdditionalReferencePaths=SameFolderYouPassToOutput? if so, that should already work 90%, id just have to fix to pass the var on fro MSBuild to EBuild.