Parcourir la source

Created new CMake function for getting visibility compiler flags.

Hidden visibility is not yet enabled for Clang, since it has problems
with templates.
Sascha Zelzer il y a 13 ans
Parent
commit
358ac843f9

+ 62 - 0
CMake/ctkFunctionGetCompilerVisibilityFlags.cmake

@@ -0,0 +1,62 @@
+
+
+#!
+#! \brief Helper macro which appends gcc compatible visibility flags to the
+#! variable given by RESULT_VAR.
+#!
+#! If supported, the flags -fvisibility=hidden and -fvisibility-inlines-hidden
+#! will be added. This applies to gcc >= 4.5 and Clang.
+#!
+#! Usage:
+#!   ctkFunctionGetCompilerVisibilityFlags(RESULT_VAR)
+#!
+#! Example:
+#!
+#! \code
+#! set(myflags "-Werror")
+#! ctkFunctionGetCompilerVisibilityFlags(myflags)
+#! \endcode
+#!
+#! The variable \emph myflags will contain the string "-Werror -fvisibility -fvisibility-inlines-hidden"
+#! if for example gcc 4.6 is used.
+#!
+#! \ingroup CMakeUtilities
+function(ctkFunctionGetCompilerVisibilityFlags RESULT_VAR)
+  
+  # We only support hidden visibility for gcc for now. Clang 3.0 still has troubles with
+  # correctly marking template declarations and explicit template instantiations as exported.
+  # See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028
+  # and http://llvm.org/bugs/show_bug.cgi?id=10113
+  set(use_visibility_flags 0)
+
+  if(CMAKE_COMPILER_IS_GNUCXX)
+  
+    set(use_visibility_flags 1)
+    ctkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION)
+  
+    # MinGW does not export all symbols automatically, so no need to set flags.
+    #
+    # With gcc < 4.5, RTTI symbols from classes declared in third-party libraries
+    # which are not "gcc visibility aware" are marked with hidden visibility in
+    # DSOs which include the class declaration and which are compiled with
+    # hidden visibility. This leads to dynamic_cast and exception handling problems.
+    # While this problem could be worked around by sandwiching the include
+    # directives for the third-party headers between "#pragma visibility push/pop"
+    # statements, it is generally safer to just use default visibility with
+    # gcc < 4.5.
+    
+    if(${GCC_VERSION} VERSION_LESS "4.5" OR MINGW)
+      set(use_visibility_flags 0)
+    endif()
+    
+  endif()
+  
+  if(use_visibility_flags)
+    set(visibility_flags "")
+    ctkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_flags)
+    ctkFunctionCheckCompilerFlags("-fvisibility-inlines-hidden" visibility_flags)
+    set(${RESULT_VAR} "${${RESULT_VAR}} ${visibility_flags}" PARENT_SCOPE)
+  endif()
+  
+endfunction()
+

+ 1 - 14
CMake/ctkMacroBuildPlugin.cmake

@@ -300,20 +300,7 @@ macro(ctkMacroBuildPlugin)
   endforeach()
 
   set(plugin_compile_flags "-DQT_PLUGIN")
-
-  # MinGW does not export all symbols automatically, so no need to set flags.
-  #
-  # With gcc < 4.5, RTTI symbols from classes declared in third-party libraries
-  # which are not "gcc visibility aware" are marked with hidden visibility in
-  # DSOs which include the class declaration and which are compiled with
-  # hidden visibility. This leads to dynamic_cast and exception handling problems.
-  # While this problem could be worked around by sandwiching the include
-  # directives for the third-party headers between "#pragma visibility push/pop"
-  # statements, it is generally safer to just use default visibility with
-  # gcc < 4.5.
-  if(CMAKE_COMPILER_IS_GNUCXX AND NOT ${GCC_VERSION} VERSION_LESS "4.5" AND NOT MINGW)
-    set(plugin_compile_flags "${plugin_compile_flags} -fvisibility=hidden -fvisibility-inlines-hidden")
-  endif()
+  ctkFunctionGetCompilerVisibilityFlags(plugin_compile_flags)
 
   # Apply properties to the library target.
   set_target_properties(${lib_name} PROPERTIES

+ 4 - 15
CMakeLists.txt

@@ -200,6 +200,7 @@ include(CMake/ctkFunctionCheckCompilerFlags.cmake)
 include(CMake/ctkFunctionGetIncludeDirs.cmake)
 include(CMake/ctkFunctionGetLibraryDirs.cmake)
 include(CMake/ctkFunctionGetGccVersion.cmake)
+include(CMake/ctkFunctionGetCompilerVisibilityFlags.cmake)
 include(CMake/ctkFunctionCompileSnippets.cmake)
 
 #-----------------------------------------------------------------------------
@@ -270,21 +271,7 @@ mark_as_advanced(ADDITIONAL_CXX_FLAGS)
 # Set symbol visibility Flags
 #
 
-ctkFunctionGetGccversion(${CMAKE_CXX_COMPILER} GCC_VERSION)
-
-# MinGW does not export all symbols automatically, so no need to set flags.
-#
-# With gcc < 4.5, RTTI symbols from classes declared in third-party libraries
-# which are not "gcc visibility aware" are marked with hidden visibility in
-# DSOs which include the class declaration and which are compiled with
-# hidden visibility. This leads to dynamic_cast and exception handling problems.
-# While this problem could be worked around by sandwiching the include
-# directives for the third-party headers between "#pragma visibility push/pop"
-# statements, it is generally safer to just use default visibility with
-# gcc < 4.5.
-if(CMAKE_COMPILER_IS_GNUCXX AND NOT ${GCC_VERSION} VERSION_LESS "4.5" AND NOT MINGW)
-  set(VISIBILITY_CXX_FLAGS "-fvisibility=hidden -fvisibility-inlines-hidden")
-endif()
+ctkFunctionGetCompilerVisibilityFlags(VISIBILITY_CXX_FLAGS)
 
 #-----------------------------------------------------------------------------
 # Set coverage Flags
@@ -308,6 +295,8 @@ if(CMAKE_COMPILER_IS_GNUCXX)
 
   ctkFunctionCheckCompilerFlags("-fdiagnostics-show-option" cflags)
   ctkFunctionCheckCompilerFlags("-Wl,--no-undefined" cflags)
+  
+  ctkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION)
 
   # With older version of gcc supporting the flag -fstack-protector-all, an extra dependency to libssp.so
   # is introduced. If gcc is smaller than 4.4.0 and the build type is Release let's not include the flag.

+ 2 - 0
CTKConfig.cmake.in

@@ -48,6 +48,8 @@ ENDIF()
 
 # Include CTK macros
 INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkFunctionGetGccVersion.cmake")
+INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkFunctionCheckCompilerFlags.cmake")
+INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkFunctionGetCompilerVisibilityFlags.cmake")
 INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkMacroParseArguments.cmake")
 INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkMacroSetPaths.cmake")
 INCLUDE("@CTK_CMAKE_DIR_CONFIG@/ctkMacroListFilter.cmake")