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")
Related
In Visual Studio 2013/VC++ for a statically linked executable, how do I override a property setting, when it is in bold( not inherited) by using a property sheet? I cannot edit the vcxproj file as it is auto generated and direct edits are lost when it is generated.
Details:
I have a Visual studio solution that contains two projects:
Dependency.vcxproj --> Generates Dependency.lib which is a static library.
MyProg.vcxproj --> Links to Dependency.lib and generates MyProg.exe
Of these, Dependency.vcxproj is auto generated and I do not have control over its generation( It is generated from a build script every time I run it). I see that It has Optimization set to O2 and also has Debug Information Format set to none. ( Both of these are in bold - so I assume they have been explicitly turned off). However, to allow for debug, I want to override these properties and set Optimization Disabled and Debug Information Format to /Zi when I am building it as part of my solution.
I tried overriding it using a .props file for the project, but the values are not overridden - I read somewhere that a property needs to inherit for a props sheet to override.
Is there any way to override such an already modified property without editing the vcxproj file itself?
You need to make sure you lib project is actually using your .props file. Means, it has to be included in the project. If you want to override already defined property with .props, this .props needs to be included after the property is set to override it. Basically .props work similar to text inclusion.
Another option could be to use .user file to override the properties (.user may be already included into generated .vcxproj, with condition "if exists"). But anyways you need to find a way to include your file re-defining the linker properties into the .vcxproj file.
Normally, you use "debug" vs "release" configurations to allow/disallow debugging. Maybe you just need to select "debug" configuration for your solution (this one can be found in the toolbar, a combo box in Visual studio) and then build?
If this is not the case, I would say the easiest way out may be modifying the script you use to generate the project to generate the project you want.
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.
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.
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.
I have multiple native C++ projects, one of them is a dll project, and I want to test it.
The problem is that the generated .lib file only contains the definitions for the public interface of the dll, but I would like to test the projects internals.
Since referencing the project does not work (it only works for static libraries) is there a way to add the the generated objs directly in my testing project ?
Also I know that I could include all the source code files in the referenced project. But is there a way to do this considering that the referenced project might change. I would like a method that does not force me to mange each file manually.
I have done some research and I found some answers like in this question:
Reusing object files in Visual Studio 2005
but since I have many small classes exposing all the classes is a bit to tedious.
I found that I can set a Pre Link Event in the Build Event menu.
This allows me to use the following command:
lib -out:"../Debug/tempAllDllObjects.lib" "../MyDLLProject/Debug/*.obj"
now, even if my project is a DLL project I have an additional .lib file that contains all the objects in my project. All I have to do is reference the newly created lib file. This way I can link with all the objects in my DLL project even if they are not in the public interface.
As a note the command can also be set on the DLL project as a Postbuild Event this will increase the efficiency since now the lib file is only generated when changes occur.