Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a cmake project with visual studio

Visual Studio 2017 provides built-in support for handling CMake projects. The documentation mostly covers scenarios based on pre-existing cmake projects. But is there any support for creating a cmake project without having to fiddle with the CMakeLists.txt file?

like image 517
user1934212 Avatar asked Oct 14 '17 07:10

user1934212


People also ask

How do I add a CMake project to Visual Studio solution?

On the Visual Studio main menu, choose File > Open > CMake. Navigate to the CMakeLists. txt file in the root of the bullet3 repo you just downloaded. As soon as you open the folder, your folder structure becomes visible in the Solution Explorer.

Can you use CMake with Visual Studio code?

The latest version of CMake tools is now available for download in the VS Code Marketplace or using the . vsix file. We have been working hard on improving the CMake experience and are excited to share some new features and improvements for users starting in version 1.11.

How do I run CMake code in Visual Studio?

Open the Command Palette (Ctrl+Shift+P) and run the CMake: Build command, or select the Build button from the Status bar. You can select which targets you'd like to build by selecting CMake: Set Build Target from the Command Palette. By default, CMake Tools builds all targets.


1 Answers

EDIT: VS2017 15.6 added an official New Project CMake Wizard

With version 15.6 came the feature of "Create CMake projects from the Add New Project dialog."

enter image description here

This creates a simple ninja based C++ "Hello CMake" project.

A Custom CMake Wizard

Your question and the lack of an existing Wizard inspired me to write one. It's a very basic setup and would most definitely benefit if people with more experience in writing Visual Studio extensions would contribute, but here it is:

https://github.com/FloriansGit/VSCMakeWizards

Edit: Latest VSIX installer is now also available for free on VS Marketplace

https://marketplace.visualstudio.com/items?itemName=oOFlorianOo.CMakeProjectWizards

The new "CMake Executable Template" will show up after a restart of your Visual Studio 2017 under "File/New/Project/Visual C++":

CMake Project Wizard

It generates the following files in the given folder and then uses "Open Folder" on it:

CMakeLists.txt
CMakeSettings.json
MyProject1.cpp 

Next Steps

Possible next steps would be to:

  • Add an interactive Wizard Dialog for some basic project/compiler settings
  • Add also an Item Wizard to be able to add source files to the CMakeLists.txt

I'm looking forward getting feedback on the basic idea. Please add any requests directly to:

https://github.com/FloriansGit/VSCMakeWizards/issues

The Code

And here is the Wizards basic/initial code as a reference:

WizardImplementationClass.cs

// Based on https://docs.microsoft.com/en-us/visualstudio/extensibility/how-to-use-wizards-with-project-templates
//      and https://stackoverflow.com/questions/3882764/issue-with-visual-studio-template-directory-creation

using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using EnvDTE;
using Microsoft.VisualStudio.TemplateWizard;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using EnvDTE80;

namespace VSCMakeWizards
{
    public class WizardImplementation : IWizard
    {
        public void RunStarted(object automationObject,
            Dictionary<string, string> replacementsDictionary,
            WizardRunKind runKind, object[] customParams)
        {
            var destinationDir = replacementsDictionary["$destinationdirectory$"];
            var desiredNamespace = replacementsDictionary["$safeprojectname$"];
            var templatePath = Path.GetDirectoryName((string)customParams[0]);

            var dte = automationObject as DTE2;
            var solution = dte.Solution as EnvDTE100.Solution4;

            if (solution.IsOpen)
            {
                solution.Close();
            }

            File.Copy(Path.Combine(templatePath, "CMakeSettings.json"), Path.Combine(destinationDir, "CMakeSettings.json"));
            File.Copy(Path.Combine(templatePath, "main.cpp"), Path.Combine(destinationDir, desiredNamespace + ".cpp"));

            // see https://stackoverflow.com/questions/1231768/c-sharp-string-replace-with-dictionary
            Regex re = new Regex(@"(\$\w+\$)", RegexOptions.Compiled);
            string input = File.ReadAllText(Path.Combine(templatePath, "CMakeLists.txt"));
            string output = re.Replace(input, match => replacementsDictionary[match.Groups[1].Value]);

            File.WriteAllText(Path.Combine(destinationDir, "CMakeLists.txt"), output);

            var vsSolution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution7;

            if (vsSolution != null)
            {
                vsSolution.OpenFolder(destinationDir);
            }

            throw new WizardCancelledException();
        }

        // This method is called before opening any item that   
        // has the OpenInEditor attribute.  
        public void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public void ProjectFinishedGenerating(Project project)
        {
        }

        // This method is only called for item templates,  
        // not for project templates.  
        public void ProjectItemFinishedGenerating(ProjectItem
            projectItem)
        {
        }

        // This method is called after the project is created.  
        public void RunFinished()
        {
        }

        // This method is only called for item templates,  
        // not for project templates.  
        public bool ShouldAddProjectItem(string filePath)
        {
            return false;
        }
    }
}

Note: The WizardCancelledException is necessary, because Visual Studio otherwise would try to generate/open an actual solution. An "Open Folder" kind of project wizard is not yet supported (no SDK API for this).

References

  • Issue with visual studio template & directory creation
  • C# String replace with dictionary
like image 110
Florian Avatar answered Sep 20 '22 12:09

Florian