Introduce target property <LANG>_VISIBILITY_PRESET

This is initialized by CMAKE_<LANG>_VISIBILITY_PRESET. The target
property is used as the operand to the -fvisibility= compile option
with GNU compilers and clang.
This commit is contained in:
Stephen Kelly 2013-05-18 12:12:18 +02:00
parent 5361270c6e
commit 0e9f4bc00c
22 changed files with 173 additions and 0 deletions

View File

@ -24,4 +24,5 @@ macro(__compiler_clang lang)
__compiler_gnu(${lang}) __compiler_gnu(${lang})
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
endmacro() endmacro()

View File

@ -25,6 +25,9 @@ macro(__compiler_gnu lang)
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4) if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
endif() endif()
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.2)
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
endif()
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")

View File

@ -6,5 +6,9 @@ set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.0)
set(CMAKE_C_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
endif()
set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")

View File

@ -6,5 +6,9 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
endif()
set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")

View File

@ -1684,6 +1684,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// Add shared-library flags if needed. // Add shared-library flags if needed.
this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
lang, configName); lang, configName);
this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, &target,
lang);
} }
else if(binary) else if(binary)
{ {

View File

@ -1992,6 +1992,54 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
} }
} }
//----------------------------------------------------------------------------
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;
}
std::string l(lang);
std::string compileOption = "CMAKE_" + l + "_COMPILE_OPTIONS_VISIBILITY";
const char *opt = this->Makefile->GetDefinition(compileOption.c_str());
if (!opt)
{
return;
}
std::string flagDefine = l + "_VISIBILITY_PRESET";
const char *prop = target->GetProperty(flagDefine.c_str());
if (!prop)
{
return;
}
if (strcmp(prop, "hidden") != 0
&& strcmp(prop, "default") != 0
&& strcmp(prop, "protected") != 0
&& strcmp(prop, "internal") != 0 )
{
cmOStringStream e;
e << "Target " << target->GetName() << " uses unsupported value \""
<< prop << "\" for " << flagDefine << ".";
cmSystemTools::Error(e.str().c_str());
return;
}
std::string option = std::string(opt) + prop;
this->AppendFlags(flags, option.c_str());
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
std::string const& lang, std::string const& lang,

View File

@ -143,6 +143,8 @@ public:
const char* config); const char* config);
void AddCMP0018Flags(std::string &flags, cmTarget* target, void AddCMP0018Flags(std::string &flags, cmTarget* target,
std::string const& lang, const char *config); std::string const& lang, const char *config);
void AddVisibilityPresetFlags(std::string &flags, cmTarget* target,
const char *lang);
void AddConfigVariableFlags(std::string& flags, const char* var, void AddConfigVariableFlags(std::string& flags, const char* var,
const char* config); const char* config);
///! Append flags to a string. ///! Append flags to a string.

View File

@ -271,6 +271,9 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
this->LocalGenerator->AddCMP0018Flags(flags, this->Target, this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
lang, this->ConfigName); lang, this->ConfigName);
this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
lang);
// Add include directory flags. // Add include directory flags.
this->AddIncludeFlags(flags, lang); this->AddIncludeFlags(flags, lang);

View File

@ -150,6 +150,9 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
language.c_str(), language.c_str(),
this->GetConfigName()); this->GetConfigName());
this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
language.c_str());
// Add include directory flags. // Add include directory flags.
{ {
std::vector<std::string> includes; std::vector<std::string> includes;

View File

@ -923,6 +923,24 @@ void cmTarget::DefineProperties(cmake *cm)
"A target property that can be set to override the prefix " "A target property that can be set to override the prefix "
"(such as \"lib\") on a library name."); "(such as \"lib\") on a library name.");
cm->DefineProperty
("C_VISIBILITY_PRESET", cmProperty::TARGET,
"Value for symbol visibility compile flags",
"The C_VISIBILITY_PRESET property determines 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_C_VISIBILITY_PRESET if it is set when a target is created.");
cm->DefineProperty
("CXX_VISIBILITY_PRESET", cmProperty::TARGET,
"Value for symbol visibility compile flags",
"The CXX_VISIBILITY_PRESET property determines 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_CXX_VISIBILITY_PRESET if it is set when a target is created.");
cm->DefineProperty cm->DefineProperty
("POSITION_INDEPENDENT_CODE", cmProperty::TARGET, ("POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
"Whether to create a position-independent target", "Whether to create a position-independent target",
@ -1560,6 +1578,9 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->InsertInclude(*it); this->InsertInclude(*it);
} }
this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
|| this->TargetTypeValue == cmTarget::MODULE_LIBRARY) || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
{ {

View File

@ -141,6 +141,8 @@ endmacro()
include(GenerateExportHeader) include(GenerateExportHeader)
add_subdirectory(visibility_preset)
add_compiler_export_flags() add_compiler_export_flags()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -0,0 +1,13 @@
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
if (CMAKE_CXX_FLAGS MATCHES "-fvisibility=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)
add_executable(visibility_preset_exe main.cpp)
target_link_libraries(visibility_preset_exe visibility_preset)

View File

@ -0,0 +1,9 @@
#include "visibility_preset.h"
int main()
{
VisibilityPreset vp;
vp.someMethod();
return 0;
}

View File

@ -0,0 +1,7 @@
#include "visibility_preset.h"
void VisibilityPreset::someMethod()
{
}

View File

@ -0,0 +1,13 @@
#ifndef VISIBILITY_PRESET_H
#define VISIBILITY_PRESET_H
#include "visibility_preset_export.h"
class VISIBILITY_PRESET_EXPORT VisibilityPreset
{
public:
void someMethod();
};
#endif

View File

@ -65,6 +65,22 @@ add_RunCMake_test(Languages)
add_RunCMake_test(ObjectLibrary) add_RunCMake_test(ObjectLibrary)
if(NOT WIN32) if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode) add_RunCMake_test(PositionIndependentCode)
set(SKIP_VISIBILITY 0)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 4.2)
set(SKIP_VISIBILITY 1)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Watcom
OR CMAKE_SYSTEM_NAME MATCHES IRIX64
OR CMAKE_CXX_COMPILER_ID MATCHES HP
OR CMAKE_CXX_COMPILER_ID MATCHES XL
OR CMAKE_CXX_COMPILER_ID MATCHES SunPro)
set(SKIP_VISIBILITY 1)
endif()
if (NOT SKIP_VISIBILITY)
add_RunCMake_test(VisibilityPreset)
endif()
endif() endif()
add_RunCMake_test(CompatibleInterface) add_RunCMake_test(CompatibleInterface)

View File

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 2.8)
project(${RunCMake_TEST} CXX)
# MSVC creates extra targets which pollute the stderr unless we set this.
set(CMAKE_SUPPRESS_REGENERATION TRUE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1 @@
CMake Error: Target visibility_preset uses unsupported value \"hiden\" for CXX_VISIBILITY_PRESET

View File

@ -0,0 +1,3 @@
add_library(visibility_preset SHARED lib.cpp)
set_property(TARGET visibility_preset PROPERTY CXX_VISIBILITY_PRESET hiden)

View File

@ -0,0 +1,3 @@
include(RunCMake)
run_cmake(PropertyTypo)

View File

@ -0,0 +1,5 @@
int foo(void)
{
return 42;
}