0

I'm trying to create a NuGet package that runs an external application before build. That application creates a compilationtime.h file to know the time of compilation to show it in the About dialog box.

My NuGet package has a Tools folder with the CreateCompilationTimeFile.exe and an Build folder with {packagename}.props file.

I've tried a lot of combinations to create the Pre-Build event in the {packagename}.props file but none of them is working.

I tried with this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemDefinitionGroup>
    <PreBuildEvent>
      <Command>"$(MSBuildThisFileDirectory)..\tools\CreateCompilationTimeFile.exe"</Command>
    </PreBuildEvent>
  </ItemDefinitionGroup>
</Project>

Also with this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="BeforeBuild2" BeforeTargets="Build">
      <Exec Command="$(MSBuildThisFileDirectory)..\tools\CreateCompilationTimeFile.exe"/>
  </Target>
</Project>

If I do it without the NuGet package and I do it with the next property sheet, it works correctly:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup>
    <PreBuildEvent>
      <Command>"$(SolutionDir)Tools\CreateCompilationTimeFile.exe"</Command>
    </PreBuildEvent>
  </ItemDefinitionGroup>
  <ItemGroup />
</Project>

But I want to do it with the NuGet package and not with property sheets.

What am I doing wrong? Thanks.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
joseangelmt
  • 2,018
  • 18
  • 32
  • Your second method `` should be work, why it is not working for you? Do you have any error for this method? – Leo Liu Sep 13 '18 at 09:06
  • No, I don't have any errors, but the pre-build event never runs and the file "compilationtime.h" is never created. – joseangelmt Sep 13 '18 at 09:24
  • pre-build event never runs, you make me confused. If you are use the second method, there is no any pre-build event, it replaced by the target ``, am I right? when you build your project, VS/MSBuild will execute this target before build, the CreateCompilationTimeFile.exe will be executed and generate the the file "compilationtime.h". Do I have any misunderstandings? – Leo Liu Sep 13 '18 at 09:29
  • Or creating a Pre-Build event in a NuGet Package is your goal instead of creating a NuGet package that runs an external application before build? – Leo Liu Sep 13 '18 at 09:41
  • With the second method there is effectively no "pre-build event", and indeed the program should be executed, but it is not executed. Sorry about misunderstanding. – joseangelmt Sep 13 '18 at 10:58
  • I just realized that It's working but only when I rebuild the project. If I just Build the project, the program is not executed, but when rebuild it's executed correctly. – joseangelmt Sep 13 '18 at 11:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/180011/discussion-between-joseangelmt-and-leo-liu-msft). – joseangelmt Sep 13 '18 at 16:33
  • Glad to know you have resolved this issue, please convert your update info to the answer, this can be beneficial to other community members reading this thread. Thanks :). – Leo Liu Sep 17 '18 at 08:51

1 Answers1

0

As @leo-liu-msft says, the second solution works, but it's not working as expected, as I will explain below.

If the {packagename}.props contains this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="CreateCompilationFileTimeTarget" BeforeTargets="Build">
      <Exec Command="$(MSBuildThisFileDirectory)..\tools\CreateCompilationTimeFile.exe"/>
  </Target>
</Project>

Suppose that you just created a brand new C++ project and include compilationtime.h file in one of your .cpp files:

#include "compilationtime.h"

Remember, the project is new and you don't have any compilationtime.h file jet, it is supposed to be created before the build process because of the {packagename}.props.

If you build your C++ project, you'll get a C0183 Cannot open include file: 'CompilationTime.h': No such file or directory error.

If then you open the project folder, the compilationtime.h file is not where it supposes to be.

Now comment the #include "compilationfile.h" line and compile it again. The compiler will finish without any errors and if you analyze the folder, the file will be there!

Now that your compilationfile.h already exists, edit it and change the tm_year to 0 for example:

#pragma once
static struct tm GetCompilationTime()
{
    struct tm compilationTime = { 0 };
    compilationTime.tm_year=0;
    compilationTime.tm_mon=9;
    compilationTime.tm_mday=15;
    compilationTime.tm_hour=15;
    compilationTime.tm_min=37;
    compilationTime.tm_sec=41;
    return compilationTime;
}

..and then in your .cpp file, print the year to the console:

#include "pch.h"
#include <iostream>

#include "CompilationTime.h"

int main()
{
    std::cout << GetCompilationTime().tm_year << std::endl;
}

Compile and run the program. The program will print 0 and not the current year, but if you open the compilationtime.h file, it is modified with the current year, so the compiler is behaving as if instead of BeforeTargets="Build" we had configured AfterTargets="Build".

Finally I solved the problem changing the BeforeTargets to PrepareForBuild like this:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="CreateCompilationFileTimeTarget" BeforeTargets="PrepareForBuild">
        <Exec Command="$(MSBuildThisFileDirectory)..\tools\CreateCompilationTimeFile.exe"/>
    </Target>
</Project>

and now it creates/updates the compilationtime.h file always before build as I wanted.

joseangelmt
  • 2,018
  • 18
  • 32