Value in .h file not defined in .rc file - visual-studio

I'm working on creating build configurations based on a previous question of mine. I've got the Build Configurations created, and I have conditional declarations for the different builds in a file called custom.h. It currently looks like this:
#pragma once
#if defined(ELITE_BUILD)
#define BUILD 3 // 1: personal, 2: select, 3: elite
#elif defined(SELECT_BUILD)
#define BUILD 2
#elif defined(PERSONAL_BUILD)
#define BUILD 1
#endif
In one of my .rc files there is an include for versionconfig.h that looks like this (somewhat redacted):
#if BUILD == 1
#define STRDESCRIPTION "Personal Edition"
#elif BUILD == 2
#define STRDESCRIPTION "Select Edition"
#elif BUILD == 3
#define STRDESCRIPTION "Elite Edition"
#pragma message(STRDESCRIPTION)
#endif
I added the #pragma command as a logging effort. After that include, the relevant parts of the .rc file looks like this (again, a bit redacted for brevity):
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", STRDESCRIPTION
END
END
END
When I attempt to compile this project I get the error error RC2104 : undefined keyword or key name: STRDESCRIPTION. I'm at a bit of a loss. The value exists, I can log it immediately after setting it, and there is no #undef command for it.
-- EDITED --
If I add placeholder defines outside of the if block the project will compile, but the values aren't showing up, so my problem appears to be related to conditional definitions. What's confusing me most at this point is that I can put a #pragma message command inside the conditional block and it's executed properly, but the values defined there are non-existent. Hoping someone can shed some light on this for me.

I found it. In Visual Studio you have to set pre-processor definitions for the Resource Files separately from the Project. As soon as I added ELITE_BUILD to the pre-processor section for the resource everything worked as expected.

Related

Will compiler -D flag take priority over code #define of macro variable?

I have some testing code in Fortran which basically looks like
#define test1 0
#define test2 0
#define test3 0
...
#if test1
call test1()
#endif
#if test2
call test2()
#endif
#if test3
call test3()
#endif
...
At compilation, i want to change those values using -Dtest1=1.
I've seen some answers (like here) where they say you need to put
#ifndef test1
#define test1 0
#endif
But i have a lot of those and i would prefer not to add 40 lines of definition code.
Will compilation command -D flag take priority over my hard definition without the if clause?
EDIT : So i just tested it (which i should have done anyway before asking...) and compiler -D flag does not take priority over my own definition and just pulls out a warning . So any way for it to take priority and always use the compiler flags without passing through ifndef clauses?
-D effectively adds a #define at the beginning, before reading the input. So it would be just like adding an additional #define in your source code, which would naturally produce an error (or warning) about redefining the macro.
If you want to avoid that error, use the #ifndef idiom, just like everyone else does.

DPI-C and SystemVerilog External Compilation flow issue

ModelSim User's manual (v10.1c), in page 660, talks about the default autocompile flow (using vlog) and external compilation flow to get the the DPI-C to work in ModelSim. I'm able to get the auto-compile flow to work. I'm stuck with the external compilation flow.
Problem Summary: I get an "undefined reference" error in when I try to create the .dll file in-spite of using the right export and import statements in my system verilog file.
Here are the files that make up this project:
file 1: mytest.cpp
#include<stdio.h>
#include "experiment3.h"
int mymain() {
printf("---starting test in c-domain---\n");
PrintHelloWorld();
return 0;
}
file 2: experiment3.h
#ifndef INCLUDED_EXPERIMENT3
#define INCLUDED_EXPERIMENT3
#ifdef __cplusplus
#define DPI_LINK_DECL extern "C"
#else
#define DPI_LINK_DECL
#endif
#include "svdpi.h"
DPI_LINK_DECL DPI_DLLESPEC
int
mymain();
DPI_LINK_DECL void
PrintHelloWorld();
#endif
file 3: mytb.sv
module mytb;
timeunit 1ns/1ps;
export "DPI-C" function PrintHelloWorld;
import "DPI-C" context task mymain();
function void PrintHelloWorld();
$display("HelloWorld\n");
endfunction
//start test
initial begin
#10ns;
mymain();
end
endmodule
Here are the command that I am using:
command 1 :g++ -c -IC:\intelFPGA\17.0\modelsim_ase\include -o ./mytest.o ./mytest.cpp
comments :command 1 executes without any problem
key-words :MinGW, GCC
command 2 :g++ -shared -Bsymbolic -o ./mytest.dll ./mytest.o -LC:\intelFPGA\17.0\modelsim_ase\win32aloem
comments :[1] command 2 fails when I use the mytest.cpp showed above
[2] command 2 passes when I comment out "PrintHelloWorld()" in mytest.cpp
error :c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe:
./mytest.o:mytest.cpp:(.text+0x2d): undefined
reference to '`PrintHelloWorld' collect2.exe:error:ld
returned 1 exit status
key-words :MinGW, GCC, dll
command 3 : vsim -sv_lib ../src_cpp/mytest work.mytb
comments : [1] executed in console in ModelSim
[2] works when I don't have "PrintHelloWorld()" in mytest.cpp
Most of the online DPI-C examples deal with running (CPP and .SV) everything in ModelSim. I don't want that. I want to keep the HW and SW flow separate. And, this separation does work to some extent (I have no issues with calling C functions from SV (import works fine). The roadblock is with trying to call SystemVerilog function from the C function (something seems to be wrong with the export).
Any thoughts on how I can get past this hurdle ?
Based on looking at examples, try adding -fPIC to your command 1. Then command 2 should work as is.
From my experience the final file should be a shared object (.so); not a dynamic link library (.dll). I run SystemVerilog on unix based systems, so maybe windows is different. If you run into an issue, that could be something to try.
Try changing
DPI_LINK_DECL void
PrintHelloWorld();
to
DPI_LINK_DECL DPI_DLLISPEC void
PrintHelloWorld();
(if DPI_DLLISPEC doesn't work replace it directly with __declspec(dllimport))

How can I share same Product Version between two Visual C++ projects?

I have 2 Visual C++ projects which both have an RC file where the Field Product Version is defined. How can I make both projects to get this version from a global place? Global RC file or what solutions are there?
What works well for me is adding two "Solution Items". One is a .h file that #defines some version strings, and another is the .rc file that has an include to the .h and BLOCK "StringFileInfo" that uses the defines.
Individual resource files for each project use a TEXTINCLUDE to bring in the contents of the solution's .rc.
That is a lot to take in. Let me show you what I mean...
1) The two solution items are added as so:
2) version.h has some #defines that will be used in VersionInfo.rc2
#define SOLUTIONFILEVERSION 1,00,0000,00000
#define SOLUTIONFILEVERSIONSTRING "1,00,0000,00000"
#define COPYRIGHT "Copyright 2012"
#define PRODUCTNAME "Your product name"
#define COMPANYNAME "Your company name"
3) VersionInfo.rc2 uses the defines
#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION SOLUTIONFILEVERSION
PRODUCTVERSION SOLUTIONFILEVERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", COMPANYNAME
VALUE "FileVersion", SOLUTIONFILEVERSIONSTRING
VALUE "LegalCopyright", COPYRIGHT
VALUE "ProductName", PRODUCTNAME
VALUE "ProductVersion", SOLUTIONFILEVERSIONSTRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
You will want a new line at the end of this file to make the resource compiler happy when it is included in the next step.
Another field you might like to set is "FileDescription" but that is typically on a per-project basis. Remember, this can contain anything you would like to be shared between your projects.
4) Include the VersionInfo.rc2 in each process. This is done by right clicking on the each project's .rc in the Resource View and selecting Resource Includes.
Add to the Compile-time directives: #include "../VersionInfo.rc2"
This could be done manually by adding the following to the project's .rc file but it is probably better to let Visual Studio manage everything it can for you.
3 TEXTINCLUDE
BEGIN
"#include ""../VersionInfo.rc2""\r\n"
"\0"
END
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "../VersionInfo.rc2"
/////////////////////////////////////////////////////////////////////////////
Phew....that was a mouthful. But now you should be able to change your product versions from one spot.
Ok i have solve it.
I had to add following as well at the bottom of the project's recource file
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "VersionInfo.rc2"
/////////////////////////////////////////////////////////////////////////////
Now everything works great. Thanks

Eclipse CDT syntax error on __attribute__ keyword

I would like to know if there is a way to get rid of CDT syntax error warnings when using gcc's "__attribute__" keyword.
It goes without saying that I would not like to switch off CDT syntax check.
The "ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT" definition (from ams's answer) really extsts and it called __CDT_PARSER__. For example:
#ifdef __CDT_PARSER__
#define __FILE__ "<file>"
#define __LINE__ (-1)
#define __DATE__ "<date>"
#define __TIME__ "<time>"
#endif // #ifdef __CDT_PARSER__
Hope this will be helpful.
I've not tried it, and I've not used Eclipse for some time, but here's an idea:
In the CDT settings for Eclipse (or maybe just your project) set up a predefined macro (I seem to remember you can tell it what the compiler auto-defines) named __attribute__ that takes one parameter, and expands to nothing.
Maybe I haven't explained that right. Let me try again with an example. Basically, the aim is to define a macro that works like this:
#if ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT
#define __attribute__(X) /* nothing */
#endif
but without putting anything actually in your code.
Project->Properties->C/C++ general->Path and Symbols->Symbols
Add->
Name: __attribute__(X)
Value: (leave blank)
Related links: You can use this technique basically with any offending keyword
ziu's answer is also working for XC8 Microchip compilers
Name: __interrupt
Value: (leave blank)
The function prototype now is clean:
void __interrupt ISRs(void);
And Eclipse won't complain about it.

Visual Studio with SubWCRev auto-build versioning problem

Folks,
I'm using VS2010 and trying to sync the build version of my project with my Subversion repository using SubWCRev. This is all working correctly, but I can't quite get my head around one thing. My template file consists of this :
#define MAJOR_VERSION 2
#define MINOR_VERSION 2
#define MICRO_VERSION 0
#define BUILD_VERSION $WCMODS?$WCREV$+1:$WCREV$$
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
#define BUILD_VERSION_STRING QUOTE(MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION.BUILD_VERSION)
Then in my application .RC file I have :
FILEVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_VERSION
PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_VERSION
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080004e4"
BEGIN
VALUE "FileVersion", BUILD_VERSION_STRING
VALUE "ProductVersion", BUILD_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x800, 1252
END
END
As you can probably work out, I'm trying to up the build version by 1 if there's modified code so that the build version in the EXE will match the Subversion revision number when I do a release and check the code in. The problem is that BUILD_VERSION gets expanded to x+1 or x+0 which then appears in the BUILD_VERSION_STRING as "2.2.0.227+1" which is not quite what I intended.
Does anyone with a little more experience with this know a way to achieve my aim?
Thanks in advance
#define BUILD_VERSION $WCMODS?$WCREV+1$:$WCREV$$
Im my group we only automate the update of the least significant value with the svn revision number for the projects working directory. To do this we have added a pre-build step to each project that creates and then calls a batch script that does the following:
Copy $(ProjectDir)Properties\AssemblyInfo.cs to $(ProjectDir)Properties\AssemblyInfo.cs.template.
Find AssemblyVersion("X.Y.Z.ddd") in $(ProjectDir)Properties\AssemblyInfo.cs.template and replace with AssemblyVersion("X.Y.Z.$WCREV$").
Find AssemblyFileVersion("X.Y.Z.ddd") in $(ProjectDir)Properties\AssemblyInfo.cs.template and replace with AssemblyFileVersion("X.Y.Z.$WCREV$").
Run 'SubWCRev $(ProjectDir) $(ProjectDir)Properties\AssemblyInfo.cs.template $(ProjectDir)Properties\AssemblyInfo.cs'
If you use subwcrev to generate an unversioned header from your versioned template, then #include the unversioned header in your versioned .RC file, you can build for release from an unmodified work area.
Then you can just use
#define BUILD_VERSION $WCREV$
This also removes the risk of any changes creeping in between building your release EXE and checking in the code.
Could you do something like:
#define MOD_VERSION $WCMODS?1:0$
#define REVISION $WCREV$
#define BUILD_VERSION ( REVISION + MOD_VERSION )
Edit: This won't work either as pointed out in the comments!
What is the purpose of your version number? If it's to get back to the source code used to produce the binary then you might be shooting yourself in the foot a bit here. What happens if someone checks some more code into the repository at the same time as you're creating your version number? You're going to end up with your binary referencing different code.
What might be better would be to check to see if the working copy has any modifications or mixed revisions and use a specific revision number (e.g. 0xFFFFFFFF or 0) to represent this. And only use the true revision number if you used a clean tree to build the binary.
#define MAJOR_VERSION 2
#define MINOR_VERSION 2
#define MICRO_VERSION 0
#if $WCMODS?1:0$
#define BUILD_VERSION 0
#else
#define BUILD_VERSION $WCREV$
#endif

Resources