2

I am using cmake to generate a Windows/VisualStudio solution of a multi-platform C++ project.

There is a specific entry (a simple path to a folder data) in project's properties that I would like cmake to fill in for me. This entry is added by an external plug-in I cannot modify.

Filling the option in VS project properties adds the following entry in the MyAppExecutable.vcxproj file :

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|PLATFORM'">
  <AppDataFolder>D:\myappdata</AppDataFolder>
</PropertyGroup>

I would like cmake to add this AppDataFolder value for me.

It would be even better if it could set it at once for all possible PLATFORM, and whether compiling in Release, Debug or whatever else. Hopefully adding it inside <PropertyGroup Label="Globals"> would achieve this objective ?

Is there a way to make cmake set this value inside the project's file ?

teupoui
  • 293
  • 3
  • 15
  • 1
    You can try `set_target_properties(MyAppExecutable PROPERTIES VS_GLOBAL_AppDataFolder "D:\\myappdata")` – Florian Nov 22 '17 at 12:26
  • I tried it and it works ! Thanks for the suggestion. Can you make an answer, so that I can select it as the solution ? – teupoui Nov 22 '17 at 13:48
  • You're welcome. Put my comment into an answer. I think you can even use `$` generator expression if the path is known to CMake (to avoid manually converting to backslashes). – Florian Nov 22 '17 at 13:52

2 Answers2

6

Turning my comment into an answer

For setting a global VS project property you can use the VS_GLOBAL_<variable> target property:

set_target_properties(MyAppExecutable PROPERTIES VS_GLOBAL_AppDataFolder "D:\\myappdata")

Reference

Florian
  • 39,996
  • 9
  • 133
  • 149
  • I think this will put the the tag in the non config specific . Do you know if there is a way to put it in the tag? – Knitschi Dec 02 '22 at 07:01
0

A way of doing it could be to generate a PowerShell script and make cmake call it at the end of the generation process.

Here is an example of PowerShell script I have written :

$myvcxprojpath = 'D:\build\myapp\PLATFORM\MyAppExecutable.vcxproj'
$mydatapath = 'D:\myappdata'

[xml]$xml = (Get-Content $myvcxprojpath)
$globalpropgroup = $xml.Project.PropertyGroup | where {$_.Label -eq 'Globals'}
$datapath = $globalpropgroup.AppDataFolder
if ($datapath -eq $null)
{
    $newNode = $xml.CreateElement("AppDataFolder")
    $newNode.set_InnerXML($mydatapath)
    $globalpropgroup.AppendChild($newNode)
}
else
{
    $globalpropgroup.AppDataFolder= $mydatapath
}
$xml = [xml]$xml.OuterXml.Replace(" xmlns=`"`"", "")
$xml.Save($myvcxprojpath)

This script looks for the AppDataFolder entry. If it is not present it creates one ; in the other case it simply updates its content.

I had to add a line to remove the empty xmlns label in the new xml node.

teupoui
  • 293
  • 3
  • 15