Conditionally exclude project from Visual Studio build - visual-studio-2012

I have a Visual Studio 2012 library project (VC++) that includes certain classes if a certain SDK is available. I implemented this via msbuild Conditions in a property sheet:
<Choose>
<When Condition="Exists('C:\OFED_SDK\')">
<PropertyGroup>
<OfedSdkDir>C:\OFED_SDK\</OfedSdkDir>
</PropertyGroup>
</When>
</Choose>
[...]
<ItemDefinitionGroup Condition="$(OfedSdkDir) != ''">
<ClCompile>
<AdditionalIncludeDirectories>$(OfedSdkDir)Inc\; %(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_OFED_SDK; %(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
[...]
Certain functionality is only available if HAVE_OFED_SDK is defined. This works perfectly.
The solution furthermore contains several projects for testing the library project. The test for the classes compiled conditionally are in a separate project.
My question is: Can I build this project depending on whether the above-mentioned condition (Condition="$(OfedSdkDir) != '' is true? If so, how would I do that? I need a solution that also works when building from VS.
Edit: I am aware of the solution Martin proposed, but I am looking for a solution that is working programmatically, ie which does not allow the user to enable the "wrong" configuration via the GUI.
Edit: I found that I can add (Condition="$(OfedSdkDir) != '' to the ClCompile of the source file which almost achieves what I want, but still runs the build process for the project.

Just setup a different solution configuration that doesn't attempt to build the relevant projects that you want to exclude.
For example, call it "Release-No-OFED" and un-tick those projects from being compiled in that configuration.

Related

How to reuse Specflow steps from a CodedUITest project in different solution

We have Specflow layer on top of our CodedUITest project. We have some common steps in one CodedUITest project(CodedUITestProject1), which we want to use in another CodedUITest project (CodedUITestProejct2) in different solution.
We have created dll of the CodedUITestProject1 and added its reference in CodedUITestProejct2. Also updated the CodedUITestProject2's App.config file to use bindings from External Assembly like this, but is not working. Any thoughts on this.
<specFlow>
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config -->
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config --><unitTestProvider name="MsTest" />
<plugins>
<add name="CodedUi" type="Generator" path="." />
</plugins>
<stepAssemblies>
<stepAssembly assembly="CodedUITestProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</stepAssemblies>
</specFlow>
The Visual Studio Integration has some bugs when it comes to additional step assemblies.
So syntax highlighting, IntelliSense and "Go To Definition" can sometimes not work.
Try to delete the specflow-stepmap* files from %temp%.
There are no problems at runtime.
Sometimes VS decides on its own to not copy the referenced DLL if no code usages are done in the consuming project.
Double check your bin folder for CodedUITestProject1.dll it should be missing if VS has decided that you don't need it.
If this is the case then you may need to create a dummy instance of a type from CodedUITestProject1.dll in your hooks (or anywhere in the code) so VS can see that you are using something from CodedUITestProject1.dll. Once the project is built then you may remove the dummy code you have entered.
Another option could be just to References -> CodedUITestProject1 -> Properties-> Set copy local to True. (not confirmed its fixing the problem).
Note: When using BDD steps from external DLL navigation (F12 on a step) is not working.

How to set Wix OutputName programmatically

We have a Wix bundle project and now need to produce an OEM-branded version of our product. I'd like to use the same bundle project to produce both the base product and branded bundles rather than creating a second bundle project.
I'm familiar the Wix localization functionality (WXL files), and it looks like I could use it for this, but I'm stuck on the OutputName of the bundle EXE which is defined in the WIXPROJ; it needs to have a different name for the branded version. That is, the same bundle project should produce both BrandedBundle.exe and BaseProductBundle.exe.
Is there a way to use the localization functionality to set the OutputName programmatically?
I don't know how to do it with the localization functionality, but there is a nother way to do this.
You can pass in a build parameter to the msbuild...
msbuild WiXInstaller.wixproj /t:Rebuild /p:DesiredName="OEMName"
If your Output name (in the wixproj) is defined as the following:
Application-$(DesiredName)
Then your output will actually be: Application-OEMName.msi
You can then have your build configured to run for a bunch of different OEM's if you need...
msbuild WiXInstaller.wixproj /t:Rebuild /p:DesiredName="OEMOne"
msbuild WiXInstaller.wixproj /t:Rebuild /p:DesiredName="OEMTwo"
msbuild WiXInstaller.wixproj /t:Rebuild /p:DesiredName="OEMThree"
It will run the build three times, and each will have its own output name:
Application-OEMOne.msi
Application-OEMTwo.msi
Application-OEMThree.msi
Best of luck.
Upon further review, I see that the "Cultures to build" field in the bundle's project properties page is disabled, so it appears that localization is not supported for bundles.
I did find some suggestions here: Creating localized WIX 3.6 bootstrappers., but it does not appear that it is possible to do what I wanted to do (change the OutputName) the way I wanted to do it (using localization).

How are project interdependencies managed in MS Visual C++?

Probably a pretty fundamental question. When developing a single-project-solution in MSVC++ everything makes a lot of sense, every file is visible to the compiler. When moving to a multiple project solution, none of the interface elements governing project dependence seem to make sense (coming from a .net background.)
For starters it appears setting up project dependencies with that terminology seems to only imply what order the projects are compiled in. There is no more function attached to the definition and addressing objects or methods of one project from another will not work. #including the headers of the dependency doesn't seem to work either, so the dependent project cannot see the files of its dependency. Copying a link of a header from one project to another doesn't work either, where for two projects under the 'Header Files' section, the same file is referenced in both locations. Even with this header references do not work and the files are unconnected. The only way of creating a functional dependency is to add the dependency's paths to the linker/compiler search path of the dependent or worse, simply copying the files of one project to another.
Either I'm missing something or the .NET Visual Studio IDEs have succeeded at what the VC++ IDE has badly failed at.
Edit:
For the sake of asking a specific question, take the following steps for creating a solution in VC++ and I ask if the missing step(s) can be filled in:
Create empty DLL project inside new solution.
Create method in DLL project and compile.
Create new empty executable project.
Create main method in new project.
...
Have main method call function in DLL project.
Preferably fill in the missing step(s) with the most most modern/industry standard/best practice method that best maintains project modularity as intended.
From this I would expect to independently be able to extrapolate and create classes, enumerations etc. in the DLL class and access them all in the executable project, so long as I can find out how this is intended to be done.
In step 2, as per the usual C++ rules, declare the method in the header. Read up on __declspec(DllExport) since the default is that methods are internal to the DLL.
In step 5, as per the usual C++ rules, include the header. Visual C++ needs to know where the header is coming from, so you need to reference the source project. Details vary between Visual Studio versions.
In step 6, you call the method in the normal way. Since it's now declared as __declspec(DllImport), the compiler will leave it to the linker, and the linker will get it from the correct DLL.

MonoTouch Linking Native References in Debug only

I have a MonoTouch project where I want to include a reference to some native ios libraries that are only used for testing & debugging. I do not need these refereces to be compiled into the release build.
I've tried editing the .csproj file to have a Condition for the ItemGroup that links in the Native References, but they seem to be ignored.
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<NativeReference Include="some path">
<IsCxx>false</IsCxx>
<Kind>Static</Kind>
</NativeReference>
I suppose there could be some way using the Additional mtouch arguments option in the project Options window. I am unsure though.
Does anyone know how I can link a native reference for a specific build configuration only in MonoDevelop?
MonoDevelop let you provide different Addtional mtouch arguments for every configuration it defines for your project. In general it means each of the four: [Debug|Release]|iPhone[Simulator] could use different settings.
If you're manually adding a static library then it's easy to add (or remove) it from a specific target.
However if you're using bindings made with the new [LinkWith] support then those additional arguments are automagically made for you. There could be ways to hack around this (e.g. changing the Build Action) but I did not try them out.

Add Visual C++ property sheets using CMake

I'm currently porting a gcc project to Visual C++. It's defined in a CMake file, and I have created a Visual C++ property sheet to aid in compatibility (GccCompat.props). Everytime the Visual C++ project files are regenerated by CMake, the property sheet has to be added manually, since I don't know how to add it automatically. So, the question is:
How can I tell CMake to add a property sheet to the generated Visual C++ solution?
This functionality has made it into the nightly build of CMake (https://gitlab.kitware.com/cmake/cmake/commit/e390991846825799e619e072a28f1da58b7c89ba), although not into a stable release yet. Theoretically, it will be in the next release, and CMake releases are made relatively frequently.
To use, you would set the VS_USER_PROPS property on a target. Eg. set_target_properties(foo PROPERTIES VS_USER_PROPS "${props_file}").
However, it doesn't appear that you can use multiple property sheets with this option, and, it replaces the default user property file ($(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props). To workaround this, property sheets can include other property sheets, so, you could make a 'master' property sheet which includes any other property sheets that you would like to use (including the default user property sheet).
This question is a little bit old but I have recently stumbled upon the same problem while integrating GStreamer into my project. GStreamer comes with a set of extremely well prepared and high quality Property Sheets and I wanted to use them instead of hacking things around in CMake.
Fortunately, this issue is only limited to Windows and Visual Studio. So here's my solution:
The idea is to use Visual Studio's .user file feature. CMake does not generate this file so it's pretty safe to generate it at configure-time. At configure time you may generate a file that has the EXACT name as your project file but ends with a .user extension.
Partial Solution:
If your project file is named my_project.vcxproj, you need to create another file next to it called my_project.vcxproj.user. According to MSDN:
A user file (.vcxproj.user) stores user-specific properties, for
example, debugging and deployment settings. The vcxproj.user file
applies to all projects for a particular user.
The contents of this file for importing property sheets is something like this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="/path/to/sheet1.props" />
<Import Project="/path/to/sheet2.props" />
</Project>
Not flawless, but works until CMake starts supporting property sheets. The file can be created by using CMake's file command at configure-time.
Potential Caveat:
I have noticed when I add property sheets this way, sometimes they do not show in the Property Manager window (might be a bug in Visual Studio Community 2013) but they always are imported properly and dependencies are resolved correctly.
Not sure which properties you need. A few could be set directly in CMake, like in this example for multiple configurations:
set (CMAKE_CONFIGURATION_TYPES "A;B;C;D" CACHE STRING "Configurations" FORCE)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
set (CMAKE_CXX_FLAGS_${OUTPUTCONFIG} "/ZI /Od")
set (CMAKE_EXE_LINKER_FLAGS_${OUTPUTCONFIG} "/debug")
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
Apart from variables listed here, I think CMake has no possibility to attach property sheets.
in my master props file main.props:
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
then, in CMakeLists.txt:
set_target_properties(foo PROPERTIES VS_USER_PROPS "main.props")

Resources