Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong "OutputPath" and "OutDir"? #205

Open
mcreek opened this issue Mar 22, 2022 · 5 comments
Open

Wrong "OutputPath" and "OutDir"? #205

mcreek opened this issue Mar 22, 2022 · 5 comments
Labels
Discussion/Question Discussions or questions about the code Feedback Needed Further information is requested

Comments

@mcreek
Copy link

mcreek commented Mar 22, 2022

With Buildalyzer (version 4.1.3) I'm analyzing CSPROJ files which are part of a solution file.
For build-output configuration I'm using one common "common.props" file instead of configuring it at all csproj files individually.

Example of file "common.props"

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        ...
        <OutputPath>$(SolutionDir)\build\bin\$(Configuration)\</OutputPath>
        ...
    </PropertyGroup>
</Project>

This "common.props" file is included in each csproj file with

<Import Project="..\..\Common.props" />

and the "OutputPath" Property is removed in each csproj file .

My directory structure is:

SampleApp
|--SampleApp.sln
|--common.props
|
|--build
|   |--bin
|       |--debug
|       |--release
|
|--src
    |--SampleAppProj_1
    |   |--SampleAppProj_1.csproj
    |   |-- ...
    |
    |--SampleAppProj_2
        |--SampleAppProj_1.csproj
        |-- ...

Analyzing the projects with code:

public void Test(string projectFile)
{
    AnalyzerManager manager = new AnalyzerManager();
    IProjectAnalyzer analyzer = manager.GetProject(projectFile);
    analyzer.SetGlobalProperty("Configuration", "debug");

    string tempDir = Path.Combine(Path.GetDirectoryName(projectFile), "Temp") + Path.DirectorySeparatorChar;
    EnvironmentOptions options = new EnvironmentOptions();
    options.GlobalProperties["IntermediateOutputPath"] = tempDir; //designation of intermediate output file directory
    options.TargetsToBuild.Remove("Clean"); //see https://github.com/daveaglick/Buildalyzer/issues/105)

    IAnalyzerResults results = analyzer.Build(options);
    IAnalyzerResult analyzerResult = results.First();

    System.Diagnostics.Debug.WriteLine(analyzerResult.GetProperty("OutputPath"));
}

This will print out for "OutputPath": "<drive>\SampleApp\src\SampleAppProj_1\\build\bin\debug"
instead of "<drive>\SampleApp\build\bin\debug"
Same for "OutDir" property.

I'am doing something wrong?
How can I get the correct "OutputPath" and "OutDir"?

@daveaglick
Copy link
Collaborator

Buildalyzer doesn't actually process the project file on its own (at least not beyond very rudimentary parsing to figure out how to call MSBuild), and the values in IAnalyzerResult come directly from MSBuild logging. So that's all to say that if the OutputPath and OutDir props aren't coming over correctly, then it's because MSBuild isn't resolving them as you expect when Buildalyzer calls it.

There's a few reasons why this could be:

  • The working path might be different from when Visual Studio or another environment runs MSBuild to when Buildalyzer does.
  • Other global props might be set that Buildalyzer doesn't know about, particularly if whatever you normally build with is setting environment variables or something.
  • Buildalyzer might be finding the wrong MSBuild that treats things differently than you expect.

The best way to diagnose what's going on here is probably to log what Buildalyzer is doing and then do it yourself from the command line. For example:

StringWriter log = new StringWriter();
AnalyzerManager manager = new AnalyzerManager(
    new AnalyzerManagerOptions
    {
        LogWriter = log
    });
// ...
System.Diagnostics.Debug.WriteLine(log.ToString());

That'll let you see exactly what command line Buildalyzer ran and from where and then you can run it yourself and compare.

The next step after that would probably be to generate a binary log and open it with the Structured Log Viewer. That should let you see exactly what's going on under the hood, how and why those output values are being set the way they are, and where or if the common.props file is being processed:

IProjectAnalyzer analyzer = manager.GetProject(projectFile);
analyzer .AddBinaryLogger("myproject.binlog")));

To really get down to what the differences are, use the Project System Tools extension to generate a binary log file from Visual Studio too and compare the two.

@daveaglick daveaglick added the Discussion/Question Discussions or questions about the code label Apr 20, 2022
@mcreek
Copy link
Author

mcreek commented Apr 22, 2022

Thank you for response and the description how to analyze it.
I will try to analyze it but I will need some time for it.

@Bertk
Copy link

Bertk commented Jan 15, 2024

Please use Directory.Build.props and Directory.Build.targets instead of "common.props".

OutputPath property is a relativ path and BaseOutputPath should be used.
image

image

see also .NET 8.0 SDK Artifacts output layout

@phmonte
Copy link
Owner

phmonte commented Apr 7, 2024

@mcreek, Do you have any updates on this?

@phmonte phmonte added the Feedback Needed Further information is requested label Apr 7, 2024
@Bertk
Copy link

Bertk commented Apr 7, 2024

This might be helpful. OutputPath vs OutDir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion/Question Discussions or questions about the code Feedback Needed Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants