I am writing several C++ libraries inside of visual studio. I know I can use the Version Resource to assign DLL's a version, product name, and so on but is there a way that I can swap out different Resource scripts depending on my configuration settings. For instance, say I am compiling for x86 I want the product name to be x86, likewise for x64 I want the product name to be x64.
You can use #ifdefs in resource files. But using #ifdefs directly in he resource files, can sometimes screw with the IDE's resource editor (it has happened for me in Visual Studio 2008). I would therefore create two resource files (e.g. resource-x86.rc and resource-x64.rc) and include them in the main rc file like this:
#ifdef X86
#include "resource-x86.rc"
#elif X64
#include "resource-x64.rc"
#else
#error Unsupported platform!
#endif
copied from here
--
Open your project in Visual Studio
Right click on resource script file (e.g. app.rc) and select "Properties"
At the top of the property page, select one platform like "Win32" or "x64".
In the left menu bar, select [Configuration Properties] / [Resources] / [General].
In the "Preprocessor Definitions" field, add "WIN32" for "Win32" platform and "WIN64" for "x64" platform. The field value will become "WINXX;_UNICODE;UNICODE". (XX will be 32 or 64)
Click OK to close the window.
Right click on resource script file (e.g. app.rc) and select "View Code".
In the code editor, add #ifdef and #elif to conditionally include resources when compiling. Use "WIN32" and "WIN64" preprocessor definitions that we defined just now.
Here is a sample code:
--------------------------------
#ifdef WIN32
IDB_BITMAP1 BITMAP "bitmap1.bmp"
IDB_BITMAP2 BITMAP "bitmap2.bmp"
#elif WIN64
IDR_TOOLBAR1 BITMAP "toolbar1.bmp"
IDI_ICON1 ICON "icon1.ico"
#endif
--------------------------------
Save the resource script file and compile the project in different platforms.
Related
In Visual Studio 2019 I have two C++ projects contained in the same Solution: ProjectA and ProjectB.
How to define a C/C++ Preprocessor Definition in ProjectB ( let's call it: THE_OTHER_FILE_NAME ), which is equal to the string returned by the VS macro $(TargetFileName) in the ProjectA ?
NOTE: Hardcoding paths in the C/C++ source files is outside the scope of this question.
To access another project's VS macro $(TargetFileName) create the following XML file:
<Project>
<PropertyGroup>
<TargetFileName_Global>__UNDEFINED__</TargetFileName_Global>
<TargetFileName_Global Condition="Exists('$(SolutionDir)TargetFileName.vsmacro')">"$([System.IO.File]::ReadAllText('$(SolutionDir)TargetFileName.vsmacro').trim())"</TargetFileName_Global>
</PropertyGroup>
</Project>
...and name it Directory.Build.props and place it into your Solution Directory (where your *.sln file resides).
Next, in Solution Explorer right-click on the ProjectA's Properties --> Configuration Properties --> Build Events --> Pre-Build Event --> Command Line and set it to:
set /P "_VSdmy=$(TargetFileName.Replace('"','').trim())" <nul> "$(SolutionDir)TargetFileName.vsmacro" ||(call,)
Next, in Solution Explorer right-click on the ProjectB's Properties --> Configuration Properties --> C/C++ --> Preprocessor --> Preprocessor Definitions and add the following code there:
THE_OTHER_FILE_NAME=$(TargetFileName_Global);
Restart Visual Studio.
Now, you can use the THE_OTHER_FILE_NAME preprocessor macro in in ProjectB's *.h, *.c and *.cpp source files at will. This macro will be defined as a string of the ProjectA's target file name.
Note, that the THE_OTHER_FILE_NAME preprocessor macro in ProjectB will have meaningful contents only after you build the ProjectA. Before that happens, this macro will be defined as __UNDEFINED__. After building ProjectA you may have to refresh the Intellisense and the syntax highlighting of this macro in your source files by performing Rescan --> Rescan Solution from the context menu. Forgetting to rescan the solution this way, affects only the Intellisense display - it does not affect the building of any of the projects.
It is possible to do this with any other macro in Visual Studio and with multiple macros in multiple projects as well.
However, this method of passing variables between projects will not work with MsBuild versions earlier than v15.0 (included in Visual Studio starting from version v2017), because older versions ignore the Directory.Build.props file. See the "Updates" section, in this article.
This method will also not work when the MsBuild property ImportDirectoryBuildTargets is set to false.
P.S.
It is also possible to instantly pass a value of an MSBuild variable between projects using the Windows Registry (even through volatile registry keys), however it is not possible to pass it so through an environment variable set by the set command, because environment variables set in this manner do not survive the termination of the process that had set them. ...and each project is built by a separate MsBuild process. The <SetEnv... task has the ability to permanently set an environment variable in the User Profile or the Local Machine through the <SetEnv Target=... attribute, and environment variables set in this manner survive even the reboot, but they are not visible to existing processes (i.e. already running VS) - only to newly spawned processes. Environment variables set by the <SetEnv... task without the Target=... attribute, do not survive the termination of the process that had set them, just like the set command.
You can include file witch you need example
my second project name is p2
path in same folder repo
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include "../p2/Header.h"
int main(){
print();
system("PAUSE");
}
header file code
#pragma once
#include <stdio.h>
void print() {
printf("Hello\n");
}
And you can cheek this question
I'm trying to build a solution which contains two projects:
COM Dll
Application using this DLL
In the COM dll, I'm trying to embed the tlb generated from the idl in the project. I have usual configuration Debug-Release and Win32-x64 pair. Now, depending on this, the tlb file is created in different path which can be referenced via $(SolutionDir)Project1\$(IntDir). How do I make my resource file reference this file each time I build with different configuration pair? Here's part of my .rc file:
#include <windows.h>
1 TEXTINCLUDE DISCARDABLE
BEGIN
"1 TYPELIB ""CalcCOMObject.tlb""\r\n\0"
END
// More info block code...
#ifndef APSTUDIO_INVOKED
// Please suggest in the line below:
1 TYPELIB "x64\\Debug\\CalcCOMObject.tlb"
#endif
I'd prefer if the resource file would still be editable in the resource editor. I'm using VS2015 to build my project. Thanks!
You pass /I $(SolutionDir)Project1\$(IntDir) to RC.EXE; in Visual Studio properties this can be found under "Resources>Additional Include Directories"
I know it is possible to add defines for Visual Studio Code in c_cpp_properties.json and I manually define __GNUC__ for my code, but is it possible to undo/remove defines that Visual Studio Code assumes for itself? For example if I set intelliSenseMode to clang-x64 the macro __clang__ is defined which completely destroys my intellisense because I don't have appropriate include files for libraries I use and include selection for __clang__ happens before __GNUC__. Same for msvc-x64 value. If I manually #undef __clang__ in my include files then everything is perfect.
Is it possible to undo macro in Visual Studio Code configuration?
Yes
First, create a header file called, say, vscode-preinclude.h. Put it anywhere; I'll assume it is in the workspace folder (the one that also has .vscode in it). Inside that file use #undef to undefine the symbols you need turned off. Example:
#undef __clang__
Next, use the Command Palette (Ctrl+Shift+P) and open "C/C++: Edit Configurations (UI)". Go down to the bottom and open "Advanced Settings". Scroll down to "Forced include", and add a line:
${workspaceFolder}/vscode-preinclude.h
That's it!
Troubleshooting
If it doesn't work, take a look at the output of the "C/C++: Log Diagnostics" command. It should show something like:
Forced Includes:
D:\WRK\LEARN\VSCODE\CPPHELLO\VSCODE-PREINCLUDE.H
in its output.
If you don't want the C++ extension to auto-configure your system includes & defines, you can set "compilerPath": "" for your configuration in your c_cpp_properties.json and the extension will stop auto-configuring you.
I have created a C++ application in Visual Studio 2008. Now I would like to add properties to the manifest such as the application name and version. Both of these properties are defined within the C++ code as pre-processor macros. Is there anyway for me to populate the manifest from these MACRO values? For example:
#define APP_NAME "MyAppName"
#define APP_VERSION "MyAppVersion"
Is there some #pragma statement that I can use to add this information to the manifest? Something like:
#pragma comment(linker, "/MANIFEST:name=" APP_NAME " version=" APP_VERSION)
I am using #define and #ifndef to strip down the exe size, i noticed the resource.h and icon.ico files eat a lot of space, so i would like to not include those in my exe at all.
How do i add rule for this that obeys my #define commands ? I could edit the resource.h, but every time i change it, it would get overwritten by Visual Studio.
Edit: i dont know what is the correct name for these resource things, but my "resource.h" includes the window menu option stuff etc.
How much is "a lot of space" that you speak of?
resource.h is used for #define-ing constants that identify resources, e.g. they're just numbers. They shouldn't be a factor in executable size.
What is a factor in executable size is the resources that you embed in the executable, specified by a *.rc file. icon.ico takes up space in the *.exe because the compiler embeds the binary of the icon into the executable file itself. This icon is specified in an *.rc file that should be somewhere in your project.
You can choose to remove the icon from the *.rc file and store it separately from the *.exe file, but it's easier to just embed it into the executable. The information for defining menus, icons, dialogs, etc. has to be stored somewhere, after all.
Edit: You can have multiple resource files, so Visual Studio doesn't overwrite your directives. Refer to http://msdn.microsoft.com/en-us/library/6t3612sk(v=VS.80).aspx to see how Visual Studio handles multiple resource files. The section called "Using Multiple Resource Files in the Same Project" seems to be relevant to your problem.
In VS2010, properties for icon resources include an item "Condition" which is described as "Specifies the preprocessor symbol that determines the inclusion of the resource".
Can you upgrade?
The edit window is disabled though, you have to jump through some hoops to set the Condition. Right-click the resource and choose "Insert Copy", then you can set the condition, then delete the original unconditional icon.
Maybe this trick would work in VS2008 as well, don't have it installed on this computer so I can't test it.