I need to begin stamping dates and version numbers into .exe files produced from our Fortran source. I understand this is done with a resource file -- which in this case is just text file - that are in the resource fold in VS. Is there a template/standard/sample for this? I'm in VS 2015.
Here's what I found:
- Right click on the the Resource Files folder in the Solution Explorer side-bar in a Visual Studio solution.
- Click Add, New Item, then "Resource File (.rc)" from the list. Then click Add
- A resource file is created in the Resource Folder. Double-clicking on the file opens it in the Resource Editor in a new tab in the open files list in VS.
- By default, the resource file contains a string table.
- Right click on the file in the resource editor and click on Add Resource from the drop-down
- From the list window, choose Version, then click New
- A standard list of "Keys" and "Values" appears. The values can be modified as required, including version number, etc. This list of keys is in its own tab in the resource editor. After modification, the list (tab) can be dismissed.
- I removed the string table by opening it, right clicking on "String Table" and choosing delete. This leaves only the version info in the resource file.
- Multiple resource files can be created, each associated with different type of builds from the same code; debug, release, chip-specific, etc.
- Once the resource file(s) are built they need only have their content changed before compiling and linking to have the resulting .exe stamped with the require information.
- There is no way to automatically update the version number in the resource file (at least not in VS 2015 - I don't know about VS 2017)
- An external process can be used to modify the resource file with the version info. It's a text file with a fixed format.
- The process needs to be run as a Pre-Build Event, changing the text values in the resouce file before it (and the rest of the code) is compiled and linked.
I know this is not part of what you are doing, but I seem to remember a post from several years back where the version information from the resource file was being used in the Fortran source itself. My main trouble with the resource file I have is that I have "types" of the same application, and the Fortran itself needs the version information as does the resource. Hence every time I manually update the version I am doing it in several places: 1) the resource file; 2) version.h which is part of the resources; 3) a local Fortran module, call it VERSION. Multiply this by the number of projects in the solution (for me this is two), and I am always running the risk of version information being out of sync.
Right. I have the same difficulty. After I worked through all this, I could see that there would a large number of (perhaps) identical resource files sitting around. Our complete system consists of several .exe files, each with their own VS solution file. Though they all share the same major (and perhaps minor) version number, they each will very likely have different build numbers (last digit in the complete version number), since bugs and fixes appear in different places at different times.
A suggestion I found on the net was to have a single file hold the major and minor version numbers and have build numbers change 'locally'. This appears to require a separate Pre-Build activity depending on (in your case) the "type" of the same application. The Pre-Build program/script/app would consult the single file hold major and minor version numbers and the appropriate local resource file (for the last build number) and increment accordingly. I haven't convinced myself (yet) that this is the best solution.
I just overcame that issue of auto-versioning a compiled dll file. Here are the steps I followed;
1- After creating the resource.rc file in the main (dll) project, I added those two line in the pre-build event;
'del resource.rc" will delete the old resource.rc file, and "auto-versioning.exe" will run auto-versioning.exe that's described next.
1- I created a new fortran project (Auto-versioning.fproj) aside from the main project that builds the dll. This project builds an executable (auto-versioning.exe) that creates (resource.rc) file and include the updated incremental version number and also, if needed, the number of days since the development of my main code (reference 1/1/2000). What auto-versioning.exe does is that it opens a current.ver file that contains the current version number, increase that version number by one at each build, write that number to resource.rc and current.ver for the subsequent build. Also, Auto-versioning.exe copies the lines from a generic fixed format resource file (resource.txt) and paste the lines in (resource.exe) except the lines of the version part.
The fortran code to build auto-versioning.exe is as follows (comments are explanatory);
program Auto_versioning implicit none character(100) vs_version,line character(19) version_line Integer(4) i,d,m,y,nd,ny,nm,dy integer::month(12) ! open the file that has the last version number (i) open(84,file='current.ver') call idate(m,d,y) dy=6210 ! number of days from 1/1/2000 until 1/1/2017 ! days in each month if not leap years month(1)=31 month(2)=28 month(3)=31 month(4)=30 month(5)=31 month(6)=30 month(7)=31 month(8)=31 month(9)=30 month(10)=31 month(11)=30 month(12)=31 ! this algorithm is applicable until feb/2020 because 2020 is a leap year do ny=2017,y-1,1 dy=dy+365 enddo do nm=1,m-1,1 dy=dy+month(nm) enddo dy=d+dy ! read the version number read(84,*)i ! start creating the resource.rc by copying from a fixed formatted resource file (resource.txt) open(85,file='resource.txt') open(86,file='resource.rc') do while (vs_version.ne.'VS_VERSION_INFO VERSIONINFO') read(85,'(63a)')vs_version vs_version=trim(vs_version) write(86,*)vs_version enddo i=i+1 ! write the updated version line in resource.rc write(86,1)dy,i write(86,2)dy,i 1 format('FILEVERSION 17,12,',i5,',',i5) 2 format('PRODUCTVERSION 17,12,',i5,',',i5) rewind(84) write(84,*)i close(84) read(85,*) read(85,*) ! continue copying from resource.txt do while(.not.eof(85)) read(85,'(63a)')line line=trim(line) write(86,*)line enddo close(85) close(86) end program