Esharp LeMP #r "path" 仅适用于 compileTime 指令中的绝对路径

Esharp LeMP #r "path" works only with absolute path in compileTime directive

我使用的是最新版本2.8.1

我尝试了项目源和二进制相对路径但没有成功。这是代码:https://github.com/dadhi/LempTest/blob/strong text9ce17d16a8d7c71fc475921e1414e5bc64d72f9d/LibWithEcs/ServiceRegistrations.ecs.include#L3

此外,我不确定如何通过 --set:key=value 传递目录。我应该用引号将键或值括起来,转义斜杠吗? 如果我成功通过,我可以在 compileTime 部分中使用 #get(key) 并以某种方式将其用于 #r 吗?

更新 - 在玩完@Qwertie 回答后

我创建了一个简单的 Test.ecs 文件来测试 --set:key=value 输出

compileTime 
{
    using C = System.Console;
    var a = #get(a);
    C.WriteLine(a);
}

这是我发现的:

至少

更新 - 将 Path 值从 MSBuild Exec 目标传递到 Lemp

我的最后一个难题是将 $(ProjectDir) 作为 set:key=value 命令行开关的值传递。 这是最终的(实际上不是,请参阅下面的更新)解决方案:

    <Target Name="LempTransform" BeforeTargets="BeforeBuild">
        <PropertyGroup>
            <ProjectDirEscaped>$(ProjectDir.Replace('\', '___'))</ProjectDirEscaped>
        </PropertyGroup>
        <!-- <Message Text="Project with escaped slashes is $(ProjectDirEscaped)" Importance="high"/> -->
        <Exec WorkingDirectory="$(ProjectDir)" 
            Command="dotnet lemp %(EcsFile.Identity) --outext=.Generated.cs --set:ProjectDir=@&quot;$(ProjectDirEscaped)&quot;" />
    </Target>

主要问题是即使使用 @&quot$(ProjectDir)&quot; 也不够,因为 ProjectDir 输出带有单斜杠的路径,如 c:\foo\bar。那么就没有办法在字符串文字中对它们进行转义。所以我最终用 string.Replace 手动替换斜杠,然后在使用 .ecs 文件中的密钥时将它们替换回去:

compileTime 
{
    ##reference(precompute(System.IO.Path.Combine(#get(ProjectDir).Replace("___", "\"), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));

    using AnotherLib;

    //...

更新 - 一个更简单的解决方案,根据@Qwertie 评论将向后替换为正斜杠

评论帮了大忙,所以我不需要 Replace 在使用模板时转义值。

首先,我将 \ 替换为 / 而不是 ___,这仍然使路径对 .NET BCL API:

有效
    <PropertyGroup>
        <ProjectDirEscaped>$(ProjectDir.Replace('\', '/'))</ProjectDirEscaped>
    </PropertyGroup>

因此,在使用 ##reference:

中的路径时,我不需要 Replace
    ##reference(precompute(System.IO.Path.Combine(#get(ProjectDir), @"..\AnotherLib\bin\Debug\netstandard2.0\AnotherLib.dll")));

#r 中的相对路径在 Visual Studio 扩展中为我工作。路径应相对于源文件位置。

要找出文件“相信”它所在的输入文件夹,请在文件顶部写入 [​​=11=],然后查看 LeMP 的输出。如果输出显示 _numget(_numinputFolder),则出现错误 - 变量未设置,但可以在命令行上设置其值:--set:#inputFolder="C:\Dev\MyFolder".

--set:之后,key=value被解析为赋值表达式,因此您应该将值括在引号中,并将反斜杠替换为双反斜杠。 (表达式语法为 LES 或当前输入语言(如果有)- --inlang=ecs 对于增强型 C#)

可以在compileTime里面使用#get(key);然而,#r 指令以非常愚蠢的方式被解析,因为该指令的语法非常愚蠢(不同于普通的 C# 字符串)。因此,无法在 #r 行上使用宏。你可能不需要破解这个限制,但如果你这样做,你可以用它的等价物替换 #r "dir\Foo.dll" Loyc tree ##reference(@"""dir\Foo.dll"""); (额外的引号是可选的)然后你可以使用修改行中的宏。

我没想到可以在 compileTime 中使用 precompute,但你可以而且它有效。所以例如你可以做 ##reference(precompute(System.IO.Path.Combine(@"dir", "Foo.dll")));.