3

In CMake, while it is a great cross platform tool, it is also great for managing complex and large configurations. One road block I am hitting is allowing an otherwise cross platform project to have special "Visual Studio" only projects. Namely, I need the output from CMake to, when compiling specific visual studio projects, to have forms designer .resx files. This ends up in an tag as follows:

<ItemGroup>
    <EmbeddedResource Include="Form1.resX">
      <DependentUpon>Form1.h</DependentUpon>
      <SubType>Designer</SubType>
    </EmbeddedResource>
</ItemGroup>

I could do this if I could write a custom rule, or write text, or otherwise have more lower level control over what goes into the visual studio .vcxproj file.

The .vcxproj.filters file has a corresponding entry:

<ItemGroup>
    <EmbeddedResource Include="Form1.resX">
      <Filter>Resource Files</Filter>
    </EmbeddedResource>
</ItemGroup>

There is also a requirement to get resource files added to the .vcxproj:

<ItemGroup>
    <ResourceCompile Include="app.rc" />
</ItemGroup>

And to the .vcxproj.filters:

<ItemGroup>
    <ResourceCompile Include="app.rc">
      <Filter>Resource Files</Filter>
    </ResourceCompile>
</ItemGroup>

Is this a code change to CMake or something that can otherwise be added? If it is a code change, a point out to where the code changes would have to be made and I can look at making the necessary updates.

DigitalInBlue
  • 299
  • 3
  • 10
  • Might be relevant: http://stackoverflow.com/questions/8183156/cmake-and-visual-studio-resource-files – arrowd Oct 29 '12 at 19:04
  • 1
    That discusses resource files, but the .resX files associate with a .h file for the designer in the .vcxproj and are again used in the .vcxproj.filters file. It is more complicated than a resource. If they are not set up properly, then the visual studio designer will not work. Since these are all just plain text items in the project files, I see no reason CMAKE couldn't be used to include them...but I'm not sure if there is some way to contort it to do this without a code change to CMAKE itself. – DigitalInBlue Oct 29 '12 at 23:51
  • 1
    Better late than never? I implemented this have done a pull request on the GitHub CMake project. Hopefully this will be an included feature in the future! – DigitalInBlue May 16 '13 at 14:02

3 Answers3

1

So it does not appear as though there is an existing solution to this problem in CMake. I modified CMake to allow it to include .resX files properly inside the Visual Studio solution files. An initial test indicates all is well, though more testing is needed. The code changes were simple enough. The issue it raised, however, is that of manually managing Visual Studio's references. CMake does have facilities for this (though the documentation is lacking). The issue is primarily bookkeeping, however there are many options that can be configured for references, resources, and the like that, while CMake will allow you to add to the projects, are not terribly configurable. I'm going to give my version a trial run and, if things go well, send it in to be included in the CMake source.

DigitalInBlue
  • 299
  • 3
  • 10
1

Now in 2018, I noticed that there is CMake source that links the .resx file to header.

if (this->ProjectType != csproj) {
    std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h";
    this->WriteElem("DependentUpon", hFileName, 3);

    for (std::string const& i : this->Configurations) {
      this->WritePlatformConfigTag("LogicalName", i, 3);
      if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") ||
          // Handle variant of VS_GLOBAL_<variable> for RootNamespace.
          this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) {
        (*this->BuildFileStream) << "$(RootNamespace).";
      }
      (*this->BuildFileStream) << "%(Filename)";
      (*this->BuildFileStream) << ".resources";
      (*this->BuildFileStream) << "</LogicalName>\n";
    }
  }

Note, I added all the .resx files just like the other sources along with headers. I also put the .resx files in the same directory as the header.

file(GLOB mytarget_SOURCES
    *.h
    *.cpp
    *.resx
)
add_executable(mytarget WIN32 ${mytarget_SOURCES})

It works when there is no root-namespace !

But I get into trouble when the file is under some namespace, for example test.vsgui.TestForm. Adding a namespace breaks the system. This is due to the logical-name section in .vcxproj file.

And VS_GLOBAL_ROOTNAMESPACE is there to rescue.

set_target_properties(mytarget PROPERTIES VS_GLOBAL_ROOTNAMESPACE "test.vsgui")

And it fixes the build/executable and resources are linked correctly.

Now to make the designer work, visual studio needs the references to the dot-net libraries. To do that we need to set VS_DOTNET_REFERENCES property.

set_target_properties(mytarget VS_DOTNET_REFERENCES "System;System.Data;System.Drawing;System.Windows.Forms")

I learnt that from here . And that is all !

KRoy
  • 1,290
  • 14
  • 10
0

You can try creating source group:

source_group(Resources FILES Form1.resX)

But that definitely won't help to get

<DependentUpon>Form1.h</DependentUpon>
<SubType>Designer</SubType>
arrowd
  • 33,231
  • 8
  • 79
  • 110
  • Is there no way to build a "macro" or the like to write directly to the visual studio project files? This is looking more and more like a code change. I'd make the change, but can anyone point me to where about in the code I might look to start to weave this in? – DigitalInBlue Oct 30 '12 at 15:58
  • Well, there are `file(READ ...)` and `file(WRITE ...)` commands, but i doubt you can use them to modify project files, since these files aren't generated at the moment while CMake runs code from `CMakeLists.txt`. So, there is no way to do this, AFAIK. – arrowd Oct 30 '12 at 17:24