浏览代码

Add a COMPILE_OPTION for a VISIBILITY_INLINES_HIDDEN target property.

This corresponds to the g++ and clang++
option -fvisibility-inlines-hidden on linux. On Windows with MinGW,
this corresponds to -fno-keep-inline-dllexport. That option is
not supported by clang currently.
Stephen Kelly 12 年之前
父节点
当前提交
cd1fa537a0

+ 2 - 0
Modules/Compiler/Clang-CXX.cmake

@@ -1,2 +1,4 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
+
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")

+ 10 - 0
Modules/Compiler/GNU-CXX.cmake

@@ -1,2 +1,12 @@
 include(Compiler/GNU)
 __compiler_gnu(CXX)
+
+if (WIN32)
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
+    set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
+  endif()
+else()
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
+    set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+  endif()
+endif()

+ 47 - 20
Source/cmLocalGenerator.cxx

@@ -1992,28 +1992,12 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
     }
 }
 
-//----------------------------------------------------------------------------
-void cmLocalGenerator
-::AddVisibilityPresetFlags(std::string &flags, cmTarget* target,
-                            const char *lang)
+static void AddVisibilityCompileOption(std::string &flags, cmTarget* target,
+                                       cmLocalGenerator *lg, const char *lang)
 {
-  int targetType = target->GetType();
-  bool suitableTarget = ((targetType == cmTarget::SHARED_LIBRARY)
-                      || (targetType == cmTarget::MODULE_LIBRARY)
-                      || (target->IsExecutableWithExports()));
-
-  if (!suitableTarget)
-    {
-    return;
-    }
-
-  if (!lang)
-    {
-    return;
-    }
   std::string l(lang);
   std::string compileOption = "CMAKE_" + l + "_COMPILE_OPTIONS_VISIBILITY";
-  const char *opt = this->Makefile->GetDefinition(compileOption.c_str());
+  const char *opt = lg->GetMakefile()->GetDefinition(compileOption.c_str());
   if (!opt)
     {
     return;
@@ -2037,7 +2021,50 @@ void cmLocalGenerator
     return;
     }
   std::string option = std::string(opt) + prop;
-  this->AppendFlags(flags, option.c_str());
+  lg->AppendFlags(flags, option.c_str());
+}
+
+static void AddInlineVisibilityCompileOption(std::string &flags,
+                                       cmTarget* target,
+                                       cmLocalGenerator *lg)
+{
+  std::string compileOption
+                = "CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN";
+  const char *opt = lg->GetMakefile()->GetDefinition(compileOption.c_str());
+  if (!opt)
+    {
+    return;
+    }
+
+  bool prop = target->GetPropertyAsBool("VISIBILITY_INLINES_HIDDEN");
+  if (!prop)
+    {
+    return;
+    }
+  lg->AppendFlags(flags, opt);
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator
+::AddVisibilityPresetFlags(std::string &flags, cmTarget* target,
+                            const char *lang)
+{
+  int targetType = target->GetType();
+  bool suitableTarget = ((targetType == cmTarget::SHARED_LIBRARY)
+                      || (targetType == cmTarget::MODULE_LIBRARY)
+                      || (target->IsExecutableWithExports()));
+
+  if (!suitableTarget)
+    {
+    return;
+    }
+
+  if (!lang)
+    {
+    return;
+    }
+  AddVisibilityCompileOption(flags, target, this, lang);
+  AddInlineVisibilityCompileOption(flags, target, this);
 }
 
 //----------------------------------------------------------------------------

+ 12 - 0
Source/cmTarget.cxx

@@ -941,6 +941,17 @@ void cmTarget::DefineProperties(cmake *cm)
      "exports.  This property is initialized by the value of the variable "
      "CMAKE_CXX_VISIBILITY_PRESET if it is set when a target is created.");
 
+  cm->DefineProperty
+    ("VISIBILITY_INLINES_HIDDEN", cmProperty::TARGET,
+     "Whether to add a compile flag to hide symbols of inline functions",
+     "The VISIBILITY_INLINES_HIDDEN property determines whether a flag for "
+     "hiding symbols for inline functions. the value passed used in "
+     "a visibility related compile option, such as -fvisibility=.  This "
+     "property only has an affect for libraries and executables with "
+     "exports.  This property is initialized by the value of the variable "
+     "CMAKE_VISIBILITY_INLINES_HIDDEN if it is set when a target is "
+     "created.");
+
   cm->DefineProperty
     ("POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
      "Whether to create a position-independent target",
@@ -1580,6 +1591,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
 
   this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
   this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
+  this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
 
   if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
       || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)

+ 4 - 0
Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt

@@ -1,9 +1,13 @@
 
 set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
 
 if (CMAKE_CXX_FLAGS MATCHES "-fvisibility=hidden")
   message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
 endif()
+if (CMAKE_CXX_FLAGS MATCHES "-fvisibility-inlines-hidden")
+  message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
+endif()
 
 add_library(visibility_preset SHARED visibility_preset.cpp)
 generate_export_header(visibility_preset)