Skip to content

Replace the check for Executable using the new variable HasRuntimeOutput and _IsExecutable #1178

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

Merged
merged 1 commit into from
May 11, 2017

Conversation

basoundr
Copy link
Contributor

@basoundr basoundr commented May 4, 2017

This variable is now used in places where we check to see if the project is an executable to
enable Auto Binding Redirect generation and F5 run.

This is in response to #1174

Tagging @nguerrera @srivatsn @davkean @dotnet/project-system for review

@nguerrera
Copy link
Contributor

@eerhardt @terrajobst This aligns with the discussion on #1070

<UsingTask TaskName="GetNearestTargetFramework" AssemblyFile="$(MicrosoftNETBuildTasksAssembly)" />
<UsingTask TaskName="NETSdkError" AssemblyFile="$(MicrosoftNETBuildTasksAssembly)" />

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unnecessary whitespace diff


<!--
<IsExecutable Condition="'$(IsExecutable)' == '' and '$(OutputType)'=='Exe'">true</IsExecutable>
<IsExecutable Condition="'$(IsExecutable)' == '' and '$(OutputType)'=='WinExe'">true</IsExecutable>
Copy link
Contributor

@nguerrera nguerrera May 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is after the use in BeforeCommon.targets and so the change won't have the effect you want.

Mind you, I'm surprised this test didn't fail:

public void It_generates_binding_redirects_if_needed()

I'm also surprised to see it doesn't check the contents of the app.config. Can you check that before and after your change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, it did fail. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move this to BeforeCommon.targets to fix it.

Copy link
Contributor

@nguerrera nguerrera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

@nguerrera
Copy link
Contributor

LGTM in principle once the ordering issue is fixed and tests pass.

@@ -304,7 +304,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
</When>

<When Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(OutputType)' == 'Exe'">
<When Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(IsExecutable)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the assumption that things like Test projects were going to set $(IsExecutable) to true. If that's the case, then I don't think these two lines should be changed.

The "Run Information" is used during F5 and dotnet run. If you try to dotnet run a Test project, will it try to execute the Test's $(TargetPath), which is a .dll on .NET Framework. Thus failing with a bad error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if Test projects are expected to set this property, I think we should think about the best name to use for this property.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eerhardt, I would think this would be valid and part of setting IsExecutable=true would involve having uses configure the F5 information (to use xunit, nunit, dotnet, etc...)

However, maybe having a separate variable to disable (or explicitly enable) F5 for some scenarios would be desirable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eerhardt

I was under the assumption that things like Test projects were going to set $(IsExecutable) to true.

Yes, thats true.

If that's the case, then I don't think these two lines should be changed.

We still need it so the Windows Application output type projects can still be run

I think we should think about the best name to use for this property.

I am open for a better name. But I feel IsExecutable conveys its purpose to the point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test projects aren't "executable". You can't double-click on it's output and expect the test to run. You can't type into a command-line C:\mytest\mytest.dll and watch the tests run.

I am open for a better name.

The list I came up with before (which we can add more to) was:

  • TreatAsExecutable
  • HasRuntimeOutput
  • HasRunnableOutput
  • HasExecutableOutput
  • IsExecutable
  • IsRunnable

I think the one I like most, given all the situations this is going to be used, is what we landed on in the project.json world: HasRuntimeOutput. The output isn't "runnable" or "executable", but instead the output is associated with a runtime, and that's why we can generate binding redirects and deps.json files that will work at runtime.

I would think this would be valid and part of setting IsExecutable=true would involve having uses configure the F5 information (to use xunit, nunit, dotnet, etc...)

That's exactly my point. Look at the rest of the code around this area that I commented on. If IsExecutable=true on a test project, the "Run Information" being returned says that you can just run the output directly:

<PropertyGroup>
  <RunCommand Condition="'$(RunCommand)' == ''">$(TargetPath)</RunCommand>
  <RunArguments Condition="'$(RunArguments)' == ''">$(StartArguments)</RunArguments>

However, maybe having a separate variable to disable (or explicitly enable) F5 for some scenarios would be desirable

Again, that's what the RunCommand property is for. If it is set, you can dotnet run or F5 this project. If it isn't set, then you can't.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Eric. Here's what I propose based on your feedback.

_IsExecutable : "private" variable that's true iff output type is exe or winexe. Use this everywhere we have OutputType == Exe. This is not an extensibility point, it is just for our own maintainability so that we don't reintroduce winexe bugs. Controls getting a run command that just launches the output exe.

HasRuntimeOutput: defaults to _IsExecutable, but overridable by test project or similar. Controls binding redirects and other runtime configuration file generation.

If something other than a (Win)Exe wants to be runnable, it supplies a custom RunCommand as it already works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant to reply to this earlier.

This sounds like a great plan. Thanks.

@srivatsn
Copy link
Contributor

srivatsn commented May 4, 2017

@codito @sbaid - This PR is introducing a IsExecutable property to denote a project as executable. With this, I think you can set IsExecutable=true in your project and set OutputType=dll. That way, I think you don't have to do the Main method generation but still have deps file be generated. Would that work?

@basoundr basoundr changed the title Replace the check for Executable using the new variable IsExecutable Replace the check for Executable using the new variable HasRuntimeSupport and _IsExecutable May 5, 2017
@basoundr basoundr changed the title Replace the check for Executable using the new variable HasRuntimeSupport and _IsExecutable Replace the check for Executable using the new variable HasRuntimeOutput and _IsExecutable May 5, 2017
@@ -18,7 +18,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_GetChildProjectCopyToPublishDirectoryItems Condition="'$(_GetChildProjectCopyToPublishDirectoryItems)' == ''">true</_GetChildProjectCopyToPublishDirectoryItems>

<!-- publishing self-contained apps should publish the native host as $(AssemblyName).exe -->
<DeployAppHost Condition=" '$(DeployAppHost)' == '' and '$(OutputType)' == 'Exe' and '$(RuntimeIdentifier)' != '' and '$(SelfContained)' == 'true'">true</DeployAppHost>
<DeployAppHost Condition=" '$(DeployAppHost)' == '' and '$(HasRuntimeOutput)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(SelfContained)' == 'true'">true</DeployAppHost>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should stay '$(OutputType)' == 'Exe' or $(_IsExecutable).. Tests won't get a $Test.exe.

@@ -210,7 +210,7 @@ Copyright (c) .NET Foundation. All rights reserved.
it requires a host in the output directory to load the app.
During "publish", all required assets are copied to the publish directory.
-->
<ItemGroup Condition="'$(SelfContained)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(OutputType)' == 'Exe'">
<ItemGroup Condition="'$(SelfContained)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(HasRuntimeOutput)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should stay '$(OutputType)' == 'Exe' or $(_IsExecutable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems _IsExecutable is the one we are looking for since we need to handle Winexe here as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment was a little vague. I meant this should either:

  • stay '$(OutputType)' == 'Exe'
    or
  • use $(_IsExecutable)

I didn't mean the MSBuild code should be '$(OutputType)' == 'Exe' or $(_IsExecutable)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to use $(_IsExecutable) in all these cases unless there's a reason to exclude WinExe but I don't think there is any such case. I think every case we did not treat exe and winexe the same was a bug.

@@ -255,7 +255,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</NativeNETCoreCopyLocalItems>
</ItemGroup>

<ItemGroup Condition="'$(SelfContained)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(OutputType)' == 'Exe'">
<ItemGroup Condition="'$(SelfContained)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(HasRuntimeOutput)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should stay '$(OutputType)' == 'Exe' or $(_IsExecutable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems _IsExecutable is the one we are looking for since we need to handle Winexe here as well

@@ -288,7 +288,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
</When>

<When Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(IsExecutable)' == 'true'">
<When Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(HasRuntimeOutput)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should stay '$(OutputType)' == 'Exe' or $(_IsExecutable). I discussed this prevously that tests are not dotnet run able, becuase you can't just run the output assembly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using _IsExecutable since that was original intent of this PR

@@ -304,7 +304,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>
</When>

<When Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(IsExecutable)' == 'true'">
<When Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(HasRuntimeOutput)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should stay '$(OutputType)' == 'Exe' or $(_IsExecutable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using _IsExecutable since that was original intent of this PR

@@ -13,6 +13,9 @@ Copyright (c) .NET Foundation. All rights reserved.

<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<_IsExecutable Condition="'$(_IsExecutable)' == '' and '$(OutputType)'=='Exe'">true</_IsExecutable>
<_IsExecutable Condition="'$(_IsExecutable)' == '' and '$(OutputType)'=='WinExe'">true</_IsExecutable>
<HasRuntimeOutput Condition="'$(HasRuntimeOutput)' == ''">_IsExecutable</HasRuntimeOutput>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be

<HasRuntimeOutput Condition="'$(HasRuntimeOutput)' == ''">$(_IsExecutable)</HasRuntimeOutput>

@@ -33,7 +33,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>

<PropertyGroup>
<GenerateRuntimeConfigurationFiles Condition=" '$(GenerateRuntimeConfigurationFiles)' == '' and '$(OutputType)' == 'exe' ">true</GenerateRuntimeConfigurationFiles>
<GenerateRuntimeConfigurationFiles Condition=" '$(GenerateRuntimeConfigurationFiles)' == '' and '$(HasRuntimeOutput)' == 'true' ">true</GenerateRuntimeConfigurationFiles>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should actually have a Is .NET Core check on it too. RuntimeConfigurationFiles don't make sense for desktop or mono.

But I don't think you have to make the change here. Someone should at some point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #1183

@basoundr
Copy link
Contributor Author

basoundr commented May 8, 2017

@dotnet-bot retest this please

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @basoundr.

@basoundr
Copy link
Contributor Author

basoundr commented May 8, 2017

@dotnet-bot retest Windows_NT_FullFramework Release please

@@ -403,7 +403,7 @@ Copyright (c) .NET Foundation. All rights reserved.
============================================================
-->

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(OutputType)' == 'Exe'">
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(HasRuntimeOutput)' == 'true'">
<ProjectCapability Include="CrossPlatformExecutable" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will light up the docker integration in VS, which I don't think should happen for test projects once they switch to not being actual exes. @codito, @saurabsa Thoughts?

<!--

<!--
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This file has only whitespace diffs. Better to rebase them away to keep the history clean.

@nguerrera
Copy link
Contributor

@dotnet-bot Test Windows_NT_FullFramework Release

…sent if the project's output has a runtime associated with it

_IsExecutable is set to true iff OutputType is Exe or WinExe. This is used to avoid bugs which does not consider WinExe output.

Replace the check for Executable using the new variable IsExecutable

HasRuntimeOutput is now used in places where we check to see if the project is an executable to
enable Auto Binding Redirect generation, deps.json and F5 run.
@codito
Copy link
Contributor

codito commented May 10, 2017

@codito @sbaid - This PR is introducing a IsExecutable property to denote a project as executable. With this, I think you can set IsExecutable=true in your project and set OutputType=dll. That way, I think you don't have to do the Main method generation but still have deps file be generated. Would that work?

@srivatsn, @basoundr yes, we can remove the entrypoint generation code and binding redirection logic as well. I think just setting HasRuntimeOutput and OutputType=dll may not work, because of this check; we can set _IsExecutable also, but it seems like a private property.

@basoundr
Copy link
Contributor Author

@dotnet-bot Test Windows_NT_FullFramework Release

@livarcocc livarcocc added this to the 2.0 milestone May 11, 2017
@livarcocc
Copy link
Contributor

@MattGertz for approval.

@basoundr basoundr merged commit 4309056 into dotnet:master May 11, 2017
@basoundr basoundr deleted the IsExecutable branch May 11, 2017 20:12
@basoundr
Copy link
Contributor Author

@codito

I think just setting HasRuntimeOutput and OutputType=dll may not work

The condition for deps generation and Binding redirects are based on the value of HasRuntimeOutput. So, as long as you set the value of HasRuntimeOutput to true, everything should just work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants