Mixed solution build fails

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).

DataModel.oxygene is a legacy project

Any idea what could be causing this?

Best Regards,

Jeroen Vandezande

Those are supported now, FTR.

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.

© Finally, EBuild will fall back got the Hint Path set on the project reference.

If you make sure the Hint path is correct, option © should do the trick and the reference should work. (if not, we’ll need to debug more, but that seems highly unlikely that ghats the case).

hth,
marc

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…

Thank you for the info!

Best Regards,

Jeroen

What I can do fore vNext is support multiple Hint Paths — would that solve the problem for you?

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)?

They do some copy operations of native dlls into the output folder is I am not mistaken…
I think they are part of the SQLite nuget package…

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’ll have. look at those. do you have the exact package name handy?

gotcha. in any case, the option’s there now, if you need it.

You mean assume a common output folder for all projects (because project B only would see its output folder, not project A’s), and look for missing .dlls there, if not found elsewhere?

The package that adds targets files is this:

related to the output folder :
We pass this to MSBuild:
/property:OutputPath=SomeCommonOutputDir
We use the destinationFolder option in Train for this

I am sure that the wrapper can fetch this folder from MSBuild and then add it to all hintpaths of all EBuild projects it is building

1 Like

Yeah, that would work.

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.

1 Like

Done.

1 Like

Thanx for this conversation and the explanation.
This helps us tracing the Build issues we see since we upgraded.

2 Likes

Thanx. this will be tricky to do cleanly, I’ll need to think about this…

Yes that is good for us… I can even change Train to handle this for us…

1 Like