On 09/18/2014 08:10 PM, Aleix Pol wrote:
> I added a CMAKE_OUTPUT_PROJECT_TARGETS variable that can be used to
> enable the generation of the file.
> I also renamed the file to ProjectTargets.json.
> 
> http://www.proli.net/meu/kdevelop/cmake-targetsdata.patch

Thanks.  I made some style updates and converted it to a patch
generated with 'git format-patch'.  See attached.  I also
attached a sample ProjectTargets.json generated for the "COnly"
test from our test suite.

I'd really like to hear from others on the file format itself.

Some comments on the format:

* A version number field is needed at the top.

* There needs to be support for multi-config generators.
  Perhaps everything that can be affected by the configuration
  needs to be inside a list that enumerates all configurations.
  In single-configuration generators the list would have only
  one entry for the CMAKE_BUILD_TYPE.  In multi-configuration
  generators it would be all of the CMAKE_CONFIGURATION_TYPES.

* Don't IDEs want to know the list of source files so they can
  be used for editing?

I haven't looked at what the Extra generators produce in a
while but since they are meant for IDEs they would be a good
reference for the information needed.  However, AFAIK there
is not an extra generator for a multi-config generator.

-Brad

>From b36c309dd2aa622692b7ae70d5270bc6d56e3251 Mon Sep 17 00:00:00 2001
Message-Id: <b36c309dd2aa622692b7ae70d5270bc6d56e3251.1411148212.git.brad.k...@kitware.com>
From: Aleix Pol <aleix...@kde.org>
Date: Fri, 19 Sep 2014 02:10:12 +0200
Subject: [PATCH] cmake: Add option to generate target metadata for IDEs

Create a CMAKE_OUTPUT_PROJECT_TARGETS option that can be used to enable
generation of a 'ProjectTargets.json' file.  Write into the file a JSON
description of the build targets that an IDE might load.
---
 Modules/CMakeGenericSystem.cmake |  5 +++
 Source/cmGlobalGenerator.cxx     | 80 +++++++++++++++++++++++++++++++++++++++-
 Source/cmGlobalGenerator.h       |  1 +
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 8a14aea..5ef28d8 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -67,6 +67,11 @@ if(CMAKE_GENERATOR MATCHES "Ninja")
   mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
 endif()
 
+set(CMAKE_OUTPUT_PROJECT_TARGETS OFF CACHE BOOL
+    "Enable/Disable output of a ProjectTargets.json file during generation."
+)
+mark_as_advanced(CMAKE_OUTPUT_PROJECT_TARGETS)
+
 # GetDefaultWindowsPrefixBase
 #
 # Compute the base directory for CMAKE_INSTALL_PREFIX based on:
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4375114..8e28fec 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2876,6 +2876,26 @@ void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile)
 }
 
 //----------------------------------------------------------------------------
+static void printBacktraceJson(const cmListFileBacktrace& bt,
+                               cmGeneratedFileStream& stream)
+{
+  stream << "[";
+  for(cmListFileBacktrace::const_iterator it = bt.begin(); it!=bt.end(); ++it)
+    {
+      const cmListFileContext& ctx = *it;
+
+      if(it!=bt.begin())
+            stream << ", ";
+
+      stream << '\"';
+      stream << ctx.FilePath;
+      stream << ':';
+      stream << ctx.Line;
+      stream << '\"';
+    }
+  stream << ']';
+}
+
 void cmGlobalGenerator::WriteSummary()
 {
   cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
@@ -2885,8 +2905,6 @@ void cmGlobalGenerator::WriteSummary()
   fname += cmake::GetCMakeFilesDirectory();
   fname += "/TargetDirectories.txt";
   cmGeneratedFileStream fout(fname.c_str());
-
-  // Generate summary information files for each target.
   for(TargetMap::const_iterator ti =
         this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
     {
@@ -2897,6 +2915,64 @@ void cmGlobalGenerator::WriteSummary()
     this->WriteSummary(ti->second);
     fout << ti->second->GetSupportDirectory() << "\n";
     }
+
+  if(mf->IsOn("CMAKE_OUTPUT_PROJECT_TARGETS"))
+    {
+    this->WriteProjectTargetsJson();
+    }
+}
+
+void cmGlobalGenerator::WriteProjectTargetsJson()
+{
+  cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+  std::string projectTargetsPath = mf->GetHomeOutputDirectory();
+  projectTargetsPath += "/ProjectTargets.json";
+  cmGeneratedFileStream aout(projectTargetsPath.c_str());
+  aout << "[\n";
+
+  // Generate summary information files for each target.
+  for(TargetMap::const_iterator ti =
+        this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
+    {
+    if ((ti->second)->GetType() == cmTarget::INTERFACE_LIBRARY)
+      {
+      continue;
+      }
+
+    cmTarget* t = ti->second;
+    aout <<
+      "  {\n"
+      "    \"name\": \"" << ti->first << "\",\n"
+      "    \"type\": \"" << cmTarget::GetTargetTypeName(t->GetType())
+         << "\",\n"
+      ;
+    if(t->GetType() != cmTarget::UTILITY)
+      {
+      aout <<
+        "    \"directory\": \"" << t->GetDirectory() << "\",\n"
+        "    \"location\": \"" << t->GetLocationForBuild() << "\",\n"
+        "    \"exportName\": \"" << t->GetExportName() << "\",\n"
+        "    \"backtrace\": "
+        ;
+      printBacktraceJson(t->GetBacktrace(), aout);
+      aout << ",\n";
+      }
+    aout <<
+      "    \"installed\": "
+         << (t->GetHaveInstallRule() ? "true" : "false") << "\n"
+      ;
+
+    TargetMap::const_iterator ti1 = ti;
+    if((++ti1) == this->TotalTargets.end())
+      {
+      aout << "  }\n";
+      }
+    else
+      {
+      aout << "  },\n";
+      }
+    }
+  aout << "]\n";
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index f166789..2c0120c 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -444,6 +444,7 @@ private:
 
   void WriteSummary();
   void WriteSummary(cmTarget* target);
+  void WriteProjectTargetsJson();
   void FinalizeTargetCompileInfo();
 
   virtual void ForceLinkerLanguages();
-- 
2.1.0

Attachment: ProjectTargets.json
Description: application/json

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to