LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Bob_Schor

In building executables, allow Pre-Build Action to modify Version Information before Version Information is used

Status: New

I am taking advantage of the recent FileVersionInfo to pull up the Version Number of the Executable at Run Time and display it for the User (who can then call me and say "Version 2.1.3.4634 crashed", and I can figure out which source this was).  I take advantage of the Pre-Build Action to create the Version Number, taking the "Build" part from the Revision Number of the Project itself (since the Pre-Build Action gives me the path to the Project, this is fairly straight-forward).

 

However, in order to get the correct Build to appear in my Executable, I must build twice.  The reason for this is that LabVIEW apparently reads the Version information before executing the Pre-Build Action, so my attempt to set it to the "correct" value is ignored until the subsequent Build.

 

Personally, I think it is illogical to have a "build Action" that silently takes place before the user-specified "Pre-Build Action", though there may well be a hidden "good reason" for this.  I would like to request, therefore, that LabVIEW include a "Feature" that specifically allows the Pre-Build Action to include not only setting the Version Information (which it currently does) but allowing this updated Version Information to be used in the current Build.  True, the work-around of "Build Twice, Use Once" works for me, but why should we need to jump through this particular (unpublished and unexpected) hoop?

 

Bob Schor

28 Comments
Bob_Preis
NI Employee (retired)

The project configuration, which includes build info, is read when the project loads, so it's too late to set/get that at build time. I can't tell from your post, but it sounds like you're getting/setting the XML directly? That's generally a good way to run into problems since the XML content (and format) is meant for internal use only.

 

That said, if you're going to edit the XML anyway, why not just hack it before loading the project?

 

In 2014, I'd recommend using the palette VI "Set Build Specification Version.vi" as an alternative to the above options.

Bob_Schor
Knight of NI

In LabVIEW 2014, I absolutely do use Set Build Specification Version, but by the time I do this (in the Pre-Build Action), it is too late.  I guess I need to "amend" my Feature Request to say that when a Build starts, the Version information should be "re-read" (maybe with Get Build Specification Version?) to allow the User to issue a meaningful Pre-Build Action.

 

Here's the sequence:  I have code, saved under Subversion or some other VCS.  The code has a Revision/Build number that is specific to the code being built.  I decide to build an Executable.  The Pre-Build Action, provided with the Project Folder Path, figures out the current Build and puts that into the Version Information's "Build".  Now the Build happens, and this code-specific number is embedded into the Executable (which doesn't have any obvious "attachment" to the Project location, which might be on another machine).  Now I run the program, which does a FileVersionInfo and displays for me (the User) the Version Info.  Wherever this Executable is deployed, it has the Version Information that includes build-time "links" to the actual code base.  And it all happens automatically with LabVIEW.

Bob_Preis
NI Employee (retired)

I see. I was not clear on how you were getting/setting the version. That VI is definitely the way to go when getting/setting the build version, so I'm glad to hear you're using it, however, it wasn't designed for this use case where the version is being updated at build time. On the backend, that VI touches the project and build configuration saved in the XML, which has already been read into memory by the time you're building.

 

The good news is, you can programmtically build in addition to programmatically getting/setting version. I would recommend using the version VIs in conjunction with Build.vi from the same Application Builder palette.

 

For what it's worth, I did investigate exposing version inside the pre-build step, but it would break backwards compatibility since the connector pane would need to change. There are solutions to that, but they outweigh the benefit to adding this feature to pre-build, since the API is already well suited for this problem. If it's not well suited for your case, let's discuss further.

Hooovahh
Proven Zealot

I was so excited when I heard about the native get and set version VIs.  My first plan was to build a tool that automatically reved the way I wanted to, adding the SVN commit information to the build version, and ensured that the installer version was the same as the EXE version.  I figured the pre-build VI was why this VI was made, and am severly disappointed that the first use case I had, was the one that it wasn't designed to support.

 

Sure I could write my own tool to make builds which revs, the version then performs the build, but I was hoping I could just use the hooks NI already put in place for running VIs as a pre-build.

Bob_Preis
NI Employee (retired)

Hi Hooovahh,

 

Versioning was not a consideration when this feature was added back in LabVIEW 2010. The problems that were being addressed by the pre/post build actions were as follows:

 

Pre-Build Actions

  • Delete files in the build directory
  • Sync to the latest VIs in a project
  • Programmatically modify VIs for certain builds

Post-Build Actions

  • Copy built files to an export
  • Run function unit tests
  • Perform operations on the built executable

It's not impossible to retrofit the pre/post VIs for a 'version' field, but since it's not currently part of the connector pane, there are issues with backwards compatibility, as I mentioned earlier. The App Builder API on the 'Application Builder' sub-palette is designed to address the programmatic workflow. Whether these calls happen in Pre-Build.vi or in another VI tool that invokes a build programmatically via Build.vi seems mostly irrelevant, since it's the same amount of code to get/set version. If you eventually plan to automate the build, you'll need to go this route anyway.

Bob_Schor
Knight of NI

Bob,

     You stated that one reason not to change is for Backward Compatibility, as the connector pattern would need to change.  Not true!!!

 

     Here is my Pre-Build Action that works in 2014 (except for that nasty problem that Version is already cached, so I need to build twice).  I've also included the "inner workings" so you can see I'm using the new 2014 Feature.  Note also that I've pre-wired the "Constant part" of the Version number, in this case, 2.0.0, and am only setting the Build U16 at Build time from the SVN Working Copy Revision.

Pre-Build ActionThis is the standard Pre-Build Template + my sub-VI

Set Build Version Info.png

Here I get the Revision number from the Project Path (folder), add it as a fourth "dotted entry" to the Version string, turn this into an array of 4 I32s, convert to U16, typecast to the 2014 Build Specification Version type, and invoke the 2014 Set Build Specification Version.  Too bad it doesn't do anything for the executable currently being built, but will change the Build Spec so the next time a build is done, the Version Number will be correct (assuming the SVN number stays the same, which can be ensured by "building twice").  Hey, a new motto for NI -- "Code Once, Build Twice".  [Sorry, Bob, couldn't resist ...].

 

BS

Bob_Preis
NI Employee (retired)

You've found a way to open a door with a screwdriver. Does that make it the key to that door? Of course not. Does the screwdriver work well for this task? Not really.

 

Like I've said, the get/set version VIs are designed to read/set data in the project file's configuration. This data is read before the build begins and that's really the issue here.

 

What those App Builder palette VIs are doing is they are opening a *brand new* project reference to your project (from the supplied path), while you're building, and then saving the project, while you're building. This is not really intended to be done in the midst of a build. But, as you've said, you've found a way to force it to work, and it's not great, but it gets the door open.

 

Ideally, we would be passing in a variant to the pre-build step with a set of documented, supported attribute name/value pairs, like 'version', and reading that variant back out from the pre-build step and infusing that new information from your VI into the build configuration which is already in memory. This is what I mean by a change to the connector pane.

 

If we go the route of reading just one very small piece of the project configuration a second time during the build, after the pre-build step, and only in the case when the user has configured a pre-build step, it begins to smell like a hack on our end. The better way to go would be to pass you the value directly and read it back, and that is a possibility, but would require updating the connector pane, which means we'd need to make our pre-build calls twice potentially -- once for the legacy pane and once again for the new pane.

Bob_Schor
Knight of NI

I'm beginning to see that my confusion is really a language problem.  I know what it is to "build" -- it is to gather those files (and their dependencies) that are listed in the Source Files, pull in all of the Dependencies, do some compilation and linking, add an icon, set some internal properties like Copyright, Version info, etc., and create an executable.

 

I interpreted "Pre-Build Action" as things that LabVIEW allowed you to do before it began the Build process, things like delete files from the Project, find the latest VIs, and potentially modify a few VIs for the build.  As they are done before the Build, whatever Actions are taken will "work" for the current build.  Once they are all done, the "build" process can begin.  

 

As it turns out, "Pre-Build" does not mean "before the Build", but rather "at an early stage of the Build Process".  This is OK, but it might be helpful to know just what actions take place before the Pre-Build Actions, and thus won't be affected by the current Build (but would likely take effect on the subsequent Build).

 

Is there an "expected use" of Set Build Specification Version that would allow LabVIEW developers to do what I tried to do, namely at build time, update the Version information before the build process?  You seemed to suggest that I could write a VI that would (a) do what is necessary to update the Version, then (b) carry out the intended Build, programmatically.  This gets us to "invert" the Versioning order, but this seems like a lot of extra work for the poor developer.  I've never tried doing a programmatic build -- is there a White Paper or a good example that could walk me through this process (if this is, after all, the "right" way to do this)?

 

I'm willing to accept that, as things are currently done, it is not practical to do the Pre-Build Actions first.  Too bad, it was a really nice idea ...

 

Bob Schor

Hooovahh
Proven Zealot

I recently posted an attempt to make this work as we would like.  It will prompt for the version, then abort the current build and tell the developer to invoke the build again, now with the build you specified.  There is also a way of invoking the build automatically but I didn't find a way to show the progress, or result.

 

http://forums.ni.com/t5/LabVIEW/Pre-Build-EXE-and-Installer-Set-Version/td-p/3149028

Bob_Schor
Knight of NI

Thanks for the idea, Hooovahh.  I never thought of simply aborting the Build the first time -- I posted my "variant" on your Idea as a Reply here.  Now if I could just surpress that Error message ...

 

BS