DigitalInBlue
DigitalInBlue

Reputation: 319

Adding Visual Studio .resx files in cmake

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.

Upvotes: 3

Views: 2179

Answers (3)

KRoy
KRoy

Reputation: 1406

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 !

Upvotes: 1

DigitalInBlue
DigitalInBlue

Reputation: 319

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.

Upvotes: 1

arrowd
arrowd

Reputation: 34401

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>

Upvotes: 0

Related Questions