diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 486e2af88..972d889aa 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/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") diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 879ab8f80..33d6093a1 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/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() diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 71dd3e9ae..dce183824 100644 --- a/Source/cmLocalGenerator.cxx +++ b/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); } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c34c3ab85..47e36fdbd 100644 --- a/Source/cmTarget.cxx +++ b/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) diff --git a/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt b/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt index ffa938057..2571d2224 100644 --- a/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt +++ b/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)