zeroc-ice / ice-builder-msbuild

Support for Slice (.ice) source files in MSBuild projects for C++ and C#
BSD 3-Clause "New" or "Revised" License
5 stars 2 forks source link

Duplicate filename different modules overwrites output #9

Closed Gulum closed 2 years ago

Gulum commented 2 years ago

Consider following situation:

Two slice files with the same name but different modules:

Test.ice module AModule { struct Test { bool active; }; }

Test.ice module AnotherModule { struct Test { bool active; }; }

The output file Test.h will be overwritten by the last .ice file compilation so that only one header file gets produced. This error usually occur when you use multiple services where possible .ice files have the same name. Our Solution is to use a custom compile script to run slice2cpp and appending the Module name to the output files. E.g. Test.AModule.h and Test.AnotherModule.h. Would be nice to have that as the default behaviour in this msbuild package :).

pepone commented 2 years ago

You can customize the output directory by setting the SliceCompile.OutputDir item metadata

see https://github.com/zeroc-ice/ice-builder-msbuild#customizing-the-slice-to-c-compilation-1

Gulum commented 2 years ago

We are adding the .ice files via nuget content files. This would force us to touch .vcxproj and change it manually before we are operatable. Is there a better way while adding the ice files via nuget to the project?

pepone commented 2 years ago

We are adding the .ice files via nuget content files

Not sure what you mean

Gulum commented 2 years ago

Files in a nuget package declared as content files as follow:

Package.nuspec

 ....
    <files>
        <file src="Slice\AnotherModule\*.ice" target="content\native\Slice\AnotherModule" />
                <file src="Slice\AModule\*.ice" target="content\native\Slice\AModule" />
    </files>

Will add the defined files during the package installation to the .vcxproj resulting in

Project.vcxproj

...
  <ItemGroup>
    <SliceCompile Include="Slice\AModule\Test.ice" />
    <SliceCompile Include="Slice\AnotherModule\Test.ice" />
  </ItemGroup>
...

Entries.

pepone commented 2 years ago

You can try to add a targets file to your NuGet package, that setups the OutputDir, in the target file you can have something like

    <ItemGroup>
        <SliceCompile Update="**\*.ice">
            <OutputDir>generated/%(SliceCompile.RelativeDir)</OutputDir>
        </SliceCompile>
    </ItemGroup>

This update syntax requires MSBuild version 16.6 and later, see https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-items?view=vs-2022#updating-metadata-on-items-in-an-itemgroup-outside-of-a-target

Gulum commented 2 years ago

This kinda works. It generates the following physical file output:

generated/%(SliceCompile.RelativeDir)/Test.h 0kb generated/%(SliceCompile.RelativeDir)/Test.cpp 0kb generated/AModule/Test.h 12kb generated/AModule/Test.cpp 20kb generated/AnotherModule/Test.h 12kb generated/AnotherModule/Test.cpp 20kb

Unfortunate the 0kb versions of the file are the ones which get added in Visual Studio. Whatever task creates those 0kb files does not expand the %(SliceCompile.RelativeDir) Macro.

pepone commented 2 years ago

it is difficult to follow without a complete example to reproduce the issue

Gulum commented 2 years ago

Test2.zip

Check the generated folder in the project folder after building the project.

pepone commented 2 years ago

I see the problem, I think the Visual Studio IceBuilder plugin isn't expanding the item metadata correctly.

This will work well for a pure MSBuild build, as a workaround you can try something like

<ItemGroup>
        <SliceCompile Update="SliceFiles\AModule\*.ice">
            <OutputDir>generated/AModule</OutputDir>
        </SliceCompile>
         <SliceCompile Update="SliceFiles\AnotherModule\*.ice">
            <OutputDir>generated/AnotherModule</OutputDir>
        </SliceCompile>
    </ItemGroup>
Gulum commented 2 years ago

Thanks for the effort. I will wait for the fix because I would need to touch a lot of projects to implement the workaround.