From 30880707c094ac5c0edd85d0857afb6fbae55326 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 13 Jul 2011 02:13:33 +0200 Subject: [PATCH] Add the GenerateExportMacro with unit tests. Reviewed-by: Marcus D. Hanwell --- Modules/GenerateExportHeader.cmake | 251 ++++++++++++++++++ Modules/exportheader.cmake.in | 30 +++ Tests/CMakeLists.txt | 2 + .../GenerateExportHeader/CMakeLists.txt | 122 +++++++++ .../exportheader_test.cpp | 82 ++++++ .../lib_shared_and_static/CMakeLists.txt | 12 + .../libshared_and_static.cpp | 91 +++++++ .../libshared_and_static.h | 58 ++++ .../lib_shared_and_statictest/CMakeLists.txt | 23 ++ .../libshared/CMakeLists.txt | 6 + .../libshared/libshared.cpp | 91 +++++++ .../libshared/libshared.h | 59 ++++ .../libsharedtest/CMakeLists.txt | 27 ++ .../libstatic/CMakeLists.txt | 8 + .../libstatic/libstatic.cpp | 87 ++++++ .../libstatic/libstatic.h | 54 ++++ .../libstatictest/CMakeLists.txt | 13 + 17 files changed, 1016 insertions(+) create mode 100644 Modules/GenerateExportHeader.cmake create mode 100644 Modules/exportheader.cmake.in create mode 100644 Tests/Module/GenerateExportHeader/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/exportheader_test.cpp create mode 100644 Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp create mode 100644 Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h create mode 100644 Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/libshared/libshared.cpp create mode 100644 Tests/Module/GenerateExportHeader/libshared/libshared.h create mode 100644 Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt create mode 100644 Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp create mode 100644 Tests/Module/GenerateExportHeader/libstatic/libstatic.h create mode 100644 Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake new file mode 100644 index 000000000..c7178999b --- /dev/null +++ b/Modules/GenerateExportHeader.cmake @@ -0,0 +1,251 @@ + +# - Function for generation of export macros for libraries +# +# This module provides the function GENERATE_EXPORT_HEADER() and the +# accompanying ADD_COMPILER_EXPORT_FLAGS() function. +# +# The GENERATE_EXPORT_HEADER function can be used to generate a file suitable +# for preprocessor inclusion which contains EXPORT macros to be used in +# library classes. +# +# GENERATE_EXPORT_HEADER( LIBRARY_TARGET +# [BASE_NAME ] +# [EXPORT_MACRO_NAME ] +# [EXPORT_FILE_NAME ] +# [DEPRECATED_NAME ] +# [NO_EXPORT_MACRO_NAME ] +# [STATIC_DEFINE ] +# ) +# +# ADD_COMPILER_EXPORT_FLAGS( [FATAL_WARNINGS] ) +# +# By default GENERATE_EXPORT_HEADER() generates macro names in a file name +# determined by the name of the library. The ADD_COMPILER_EXPORT_FLAGS macro adds +# -fvisibility=hidden to CMAKE_CXX_FLAGS if supported, and is a no-op on Windows +# which does not need extra compiler flags for exporting support. +# +# This means that in the simplest case, users of these functions will be equivalent to: +# +# add_compiler_export_flags() +# +# add_library(somelib someclass.cpp) +# +# generate_export_header(somelib) +# +# install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR}) +# +# install(FILES +# someclass.h +# ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR} +# ) +# +# And in the ABI header files: +# +# \code +# #include "somelib_export.h" +# +# class SOMELIB_EXPORT SomeClass { +# +# }; +# \endcode +# +# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BUILD_DIR} called +# somelib_export.h containing the macros SOMELIB_EXPORT, SOMELIB_NO_EXPORT, +# SOMELIB_DEPRECATED, SOMELIB_DEPRECATED_EXPORT and SOMELIB_DEPRECATED_NO_EXPORT. +# The resulting file should be installed with other headers in the library. +# +# The BASE_NAME argument can be used to override the file name and the names +# used for the macros +# +# add_library(somelib someclass.cpp) +# generate_export_header(somelib +# BASE_NAME other_name +# ) +# +# Generates a file called other_name_export.h containing the macros +# OTHER_NAME_EXPORT, OTHER_NAME_NO_EXPORT and OTHER_NAME_DEPRECATED etc. +# +# The BASE_NAME may be overridden by specifiying other options in the function. +# For example: +# +# add_library(somelib someclass.cpp) +# generate_export_header(somelib +# EXPORT_MACRO_NAME OTHER_NAME_EXPORT +# ) +# +# creates the macro OTHER_NAME_EXPORT instead of SOMELIB_EXPORT, but other macros +# and the generated file name is as default. +# +# add_library(somelib someclass.cpp) +# generate_export_header(somelib +# DEPRECATED_NAME KDE_DEPRECATED +# ) +# +# creates the macro KDE_DEPRECATED instead of SOMELIB_DEPRECATED. +# +# If LIBRARY_TARGET is a static library, macros are defined without values. +# +# If the same sources are used to create both a shared and a static library, the +# uppercased symbol ${BASE_NAME}_STATIC_DEFINE should be used when building the +# static library +# +# add_library(shared_variant SHARED ${lib_SRCS}) +# add_library(static_variant ${lib_SRCS}) +# +# generate_export_header(shared_variant BASE_NAME libshared_and_static) +# +# set_target_properties(static_variant PROPERTIES COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE) +# +# This will cause the export macros to expand to nothing when building the static library. + +include(CMakeParseArguments) +include(CheckCXXCompilerFlag) + +macro(_test_compiler_hidden_visibility) + check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY) + check_cxx_compiler_flag(-fvisibility-inlines-hidden COMPILER_HAS_HIDDEN_INLINE_VISIBILITY) + option(USE_COMPILER_HIDDEN_VISIBILITY "Use HIDDEN visibility support if available." ON) + mark_as_advanced(USE_COMPILER_HIDDEN_VISIBILITY) +endmacro() + +set(myDir ${CMAKE_CURRENT_LIST_DIR}) + +macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY) + set(DEFINE_DEPRECATED) + set(DEFINE_EXPORT) + set(DEFINE_IMPORT) + set(DEFINE_NO_EXPORT) + + if(WIN32) + set(DEFINE_DEPRECATED "__declspec(deprecated)") + else() + set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))") + endif() + + get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE) + + if(NOT ${type} STREQUAL "STATIC_LIBRARY") + if(WIN32) + set(DEFINE_EXPORT "__declspec(dllexport)") + set(DEFINE_IMPORT "__declspec(dllimport)") + elseif(CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES Intel AND UNIX)) + if(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY) + set(DEFINE_EXPORT "__attribute__((visibility(\"default\")))") + set(DEFINE_IMPORT "__attribute__((visibility(\"default\")))") + set(DEFINE_NO_EXPORT "__attribute__((visibility(\"hidden\")))") + endif() + endif() + endif() +endmacro() + +macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY) + # Option overrides + set(options) + set(oneValueArgs PREFIX_NAME BASE_NAME EXPORT_MACRO_NAME EXPORT_FILE_NAME DEPRECATED_NAME NO_EXPORT_MACRO_NAME STATIC_DEFINE) + set(multiValueArgs) + + cmake_parse_arguments(_GEH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(BASE_NAME "${TARGET_LIBRARY}") + + if(_GEH_BASE_NAME) + set(BASE_NAME ${_GEH_BASE_NAME}) + endif() + + string(TOUPPER ${BASE_NAME} BASE_NAME_UPPER) + string(TOLOWER ${BASE_NAME} BASE_NAME_LOWER) + + # Default options + set(EXPORT_MACRO_NAME "${PREFIX}${BASE_NAME_UPPER}_EXPORT") + set(NO_EXPORT_MACRO_NAME "${PREFIX}${BASE_NAME_UPPER}_NO_EXPORT") + set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME_LOWER}_export.h") + set(DEPRECATED_NAME "${PREFIX}${BASE_NAME_UPPER}_DEPRECATED") + set(STATIC_DEFINE "${PREFIX}${BASE_NAME_UPPER}_STATIC_DEFINE") + + if(_GEH_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to GENERATE_EXPORT_HEADER(): \"${_GEH_UNPARSED_ARGUMENTS}\"") + endif() + + if(_GEH_EXPORT_MACRO_NAME) + set(EXPORT_MACRO_NAME ${PREFIX}${_GEH_EXPORT_MACRO_NAME}) + endif() + if(_GEH_EXPORT_FILE_NAME) + if(IS_ABSOLUTE _GEH_EXPORT_FILE_NAME) + set(EXPORT_FILE_NAME ${_GEH_EXPORT_FILE_NAME}) + else() + set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_GEH_EXPORT_FILE_NAME}") + endif() + endif() + if(_GEH_DEPRECATED_NAME) + set(DEPRECATED_NAME ${PREFIX}${_GEH_DEPRECATED_NAME}) + endif() + if(_GEH_NO_EXPORT_MACRO_NAME) + set(NO_EXPORT_MACRO_NAME ${PREFIX}${_GEH_NO_EXPORT_MACRO_NAME}) + endif() + if(_GEH_STATIC_DEFINE) + set(STATIC_DEFINE ${PREFIX}${_GEH_STATIC_DEFINE}) + endif() + + set(INCLUDE_GUARD_NAME "${PREFIX}${EXPORT_MACRO_NAME}_H") + + configure_file(${myDir}/exportheader.cmake.in ${EXPORT_FILE_NAME} @ONLY) +endmacro() + +function(GENERATE_EXPORT_HEADER TARGET_LIBRARY) + get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE) + if(${type} STREQUAL "MODULE") + message(WARNING "This macro should not be used with libraries of type MODULE") + return() + endif() + if(NOT ${type} STREQUAL "STATIC_LIBRARY" AND NOT ${type} STREQUAL "SHARED_LIBRARY") + message(WARNING "This macro can only be used with libraries") + return() + endif() + _test_compiler_hidden_visibility() + _do_set_macro_values(${TARGET_LIBRARY}) + _do_generate_export_header(${TARGET_LIBRARY} ${ARGN}) +endfunction() + +function(add_compiler_export_flags) + + if(NOT CMAKE_COMPILER_IS_GNUCXX OR MINGW) + return() + endif() + + set(options) + set(oneValueArgs FATAL_WARNINGS) + set(multiValueArgs) + + cmake_parse_arguments(_EGHV "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(MESSAGE_TYPE WARNING) + + if(_EGHV_FATAL_WARNINGS) + set(MESSAGE_TYPE FATAL_ERROR) + endif() + + if (CMAKE_COMPILER_IS_GNUCXX) + exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info) + string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}") + # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the + # patch level, handle this here: + if(NOT _gcc_version) + string (REGEX REPLACE ".*\\(GCC\\).* ([34]\\.[0-9]) .*" "\\1.0" _gcc_version "${_gcc_version_info}") + endif() + + if(${_gcc_version} VERSION_LESS "4.2") + return() + endif() + endif() + + _test_compiler_hidden_visibility() + + if(USE_COMPILER_HIDDEN_VISIBILITY AND COMPILER_HAS_HIDDEN_VISIBILITY AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) + set (EXTRA_FLAGS "-fvisibility=hidden") + + if(COMPILER_HAS_HIDDEN_INLINE_VISIBILITY) + set (EXTRA_FLAGS "${EXTRA_FLAGS} -fvisibility-inlines-hidden") + endif() + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/Modules/exportheader.cmake.in b/Modules/exportheader.cmake.in new file mode 100644 index 000000000..083e95cbc --- /dev/null +++ b/Modules/exportheader.cmake.in @@ -0,0 +1,30 @@ + +#ifndef @INCLUDE_GUARD_NAME@ +#define @INCLUDE_GUARD_NAME@ + +#ifdef @STATIC_DEFINE@ +# define @EXPORT_MACRO_NAME@ +# define @NO_EXPORT_MACRO_NAME@ +#else +# ifndef @EXPORT_MACRO_NAME@ +# ifdef @TARGET_LIBRARY@_EXPORTS + /* We are building this library */ +# define @EXPORT_MACRO_NAME@ @DEFINE_EXPORT@ +# else + /* We are using this library */ +# define @EXPORT_MACRO_NAME@ @DEFINE_IMPORT@ +# endif +# endif + +# ifndef @NO_EXPORT_MACRO_NAME@ +# define @NO_EXPORT_MACRO_NAME@ @DEFINE_NO_EXPORT@ +# endif +#endif + +#ifndef @DEPRECATED_NAME@ +# define @DEPRECATED_NAME@ @DEFINE_DEPRECATED@ +# define @DEPRECATED_NAME@_EXPORT @EXPORT_MACRO_NAME@ @DEFINE_DEPRECATED@ +# define @DEPRECATED_NAME@_NO_EXPORT @NO_EXPORT_MACRO_NAME@ @DEFINE_DEPRECATED@ +#endif + +#endif // @INCLUDE_GUARD_NAME@ \ No newline at end of file diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4bf83b780..eececb020 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -221,6 +221,8 @@ IF(BUILD_TESTING) ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize) + ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader) + ADD_TEST(LinkFlags-prepare ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} --build-and-test diff --git a/Tests/Module/GenerateExportHeader/CMakeLists.txt b/Tests/Module/GenerateExportHeader/CMakeLists.txt new file mode 100644 index 000000000..2d6eabe06 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/CMakeLists.txt @@ -0,0 +1,122 @@ +cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR) + +project(GenerateExportHeader) + +set( CMAKE_INCLUDE_CURRENT_DIR ON ) + +macro(TEST_FAIL value msg) + if (${value}) + message (SEND_ERROR "Test fail:" ${msg} ${Out} ) + endif () +endmacro() + +macro(TEST_PASS value msg) + if (NOT ${value}) + message (SEND_ERROR "Test fail:" ${msg} ${Out} ) + endif () +endmacro() + +# We seem to get race conditions is writing this stuff to the same file at least on MinGW +# So to write to separate source and build directories, we use a count to differentiate. +set (COUNT 0) +macro(_do_build Include Library LibrarySource Source) + + math(EXPR COUNT "${COUNT} + 1" ) + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}/src.cpp" "#include \"${Include}\"\n" + "int main() { ${Source}; }\n" + ) + + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/../${LibrarySource}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}") + + if ("${Library}" STREQUAL "static_variant") + set(CONDITIONAL_STATIC_DEFINE "add_definitions(-DLIBSHARED_AND_STATIC_STATIC_DEFINE)\n") + endif() + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}/CMakeLists.txt" + "cmake_minimum_required(VERSION 2.8)\n" + + "project(compiletest)\n" + + "set(CMAKE_INCLUDE_CURRENT_DIR ON)\n" + + "include(GenerateExportHeader)\n" + + "add_compiler_export_flags()\n" + + "if(CMAKE_COMPILER_IS_GNUCXX)\n" + " add_definitions(-Werror)\n" + "else()\n" + " if(MSVC)\n" + # Treat deprecation warnings as errors. + " add_definitions(/we4996)\n" + " endif()\n" + "endif()\n" + + "if(MSVC)\n" + " add_definitions(-DCOMPILER_IS_MSVC)\n" + "endif()\n" + + "add_subdirectory(${LibrarySource})\n" + + "include_directories(${LibrarySource} \${CMAKE_CURRENT_BINARY_DIR}/${LibrarySource})\n" + + "${CONDITIONAL_STATIC_DEFINE}" + + "add_executable(compiletest src.cpp)\n" + "target_link_libraries(compiletest ${Library})\n" + ) + + try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/fail${COUNT} + ${CMAKE_CURRENT_BINARY_DIR}/test${COUNT} + compilefail + OUTPUT_VARIABLE Out + ) +endmacro() + +macro(build_fail Include Library LibrarySource Source Message) + _do_build(${Include} ${Library} ${LibrarySource} "${Source}") + test_fail(Result ${Message}) +endmacro() + +macro(build_pass Include Library LibrarySource Source Message) + _do_build(${Include} ${Library} ${LibrarySource} "${Source}") + test_pass(Result ${Message}) +endmacro() + +include(GenerateExportHeader) + +add_compiler_export_flags() + +if (MSVC) + add_definitions(-DCOMPILER_IS_MSVC) +endif() + +set(link_libraries) +macro(macro_add_test_library name) + add_subdirectory(${name}) + include_directories(${name} + ${${name}_BINARY_DIR} # For the export header. + ) + list(APPEND link_libraries ${name}) + add_subdirectory(${name}test) +endmacro() + +macro_add_test_library(libshared) +macro_add_test_library(libstatic) +add_subdirectory(lib_shared_and_static) +add_subdirectory(lib_shared_and_statictest) + +if (CMAKE_COMPILER_IS_GNUCXX) + # We deliberately call deprecated methods, and test for that elsewhere. + # No need to clutter the test output with warnings. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") +endif() + +if(MSVC) + add_definitions(/wd4996) +endif() + +add_executable(GenerateExportHeader exportheader_test.cpp) + +target_link_libraries(GenerateExportHeader ${link_libraries}) diff --git a/Tests/Module/GenerateExportHeader/exportheader_test.cpp b/Tests/Module/GenerateExportHeader/exportheader_test.cpp new file mode 100644 index 000000000..cfc1a053f --- /dev/null +++ b/Tests/Module/GenerateExportHeader/exportheader_test.cpp @@ -0,0 +1,82 @@ + +#include "libshared.h" + +#include "libstatic.h" + +// #define BUILD_FAIL + +#ifndef BUILD_FAIL +#define DOES_NOT_BUILD(function) +#else +#define DOES_NOT_BUILD(function) function +#endif + +int main() +{ + { + Libshared l; + l.libshared(); + l.libshared_exported(); + l.libshared_deprecated(); + l.libshared_not_exported(); + + DOES_NOT_BUILD(l.libshared_excluded();) + } + + { + LibsharedNotExported l; + DOES_NOT_BUILD(l.libshared();) + l.libshared_exported(); + l.libshared_deprecated(); + DOES_NOT_BUILD(l.libshared_not_exported();) + DOES_NOT_BUILD(l.libshared_excluded();) + } + + { + LibsharedExcluded l; + DOES_NOT_BUILD(l.libshared();) + l.libshared_exported(); + l.libshared_deprecated(); + DOES_NOT_BUILD(l.libshared_not_exported();) + DOES_NOT_BUILD(l.libshared_excluded();) + } + + libshared_exported(); + libshared_deprecated(); + DOES_NOT_BUILD(libshared_not_exported();) + DOES_NOT_BUILD(libshared_excluded();) + + { + Libstatic l; + l.libstatic(); + l.libstatic_exported(); + l.libstatic_deprecated(); + l.libstatic_not_exported(); + l.libstatic_excluded(); + } + + { + LibstaticNotExported l; + l.libstatic(); + l.libstatic_exported(); + l.libstatic_deprecated(); + l.libstatic_not_exported(); + l.libstatic_excluded(); + } + + { + LibstaticExcluded l; + l.libstatic(); + l.libstatic_exported(); + l.libstatic_deprecated(); + l.libstatic_not_exported(); + l.libstatic_excluded(); + } + + libstatic_exported(); + libstatic_deprecated(); + libstatic_not_exported(); + libstatic_excluded(); + + return 0; +} \ No newline at end of file diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt new file mode 100644 index 000000000..d19b6dc2f --- /dev/null +++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt @@ -0,0 +1,12 @@ +project(shared_and_static) + +set(lib_SRCS + libshared_and_static.cpp +) + +add_library(shared_variant SHARED ${lib_SRCS}) +add_library(static_variant ${lib_SRCS}) + +generate_export_header(shared_variant BASE_NAME libshared_and_static) + +set_target_properties(static_variant PROPERTIES COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE) diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp new file mode 100644 index 000000000..1e0727362 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp @@ -0,0 +1,91 @@ + +#include "libshared_and_static.h" + +int LibsharedAndStatic::libshared_and_static() const +{ + return 0; +} + +int LibsharedAndStatic::libshared_and_static_exported() const +{ + return 0; +} + +int LibsharedAndStatic::libshared_and_static_deprecated() const +{ + return 0; +} + +int LibsharedAndStatic::libshared_and_static_not_exported() const { + return 0; +} + +int LibsharedAndStatic::libshared_and_static_excluded() const { + return 0; +} + +int LibsharedAndStaticNotExported::libshared_and_static() const +{ + return 0; +} + +int LibsharedAndStaticNotExported::libshared_and_static_exported() const +{ + return 0; +} + +int LibsharedAndStaticNotExported::libshared_and_static_deprecated() const +{ + return 0; +} + +int LibsharedAndStaticNotExported::libshared_and_static_not_exported() const { + return 0; +} + +int LibsharedAndStaticNotExported::libshared_and_static_excluded() const { + return 0; +} + +int LibsharedAndStaticExcluded::libshared_and_static() const +{ + return 0; +} + +int LibsharedAndStaticExcluded::libshared_and_static_exported() const +{ + return 0; +} + +int LibsharedAndStaticExcluded::libshared_and_static_deprecated() const +{ + return 0; +} + +int LibsharedAndStaticExcluded::libshared_and_static_not_exported() const { + return 0; +} + +int LibsharedAndStaticExcluded::libshared_and_static_excluded() const { + return 0; +} + +int libshared_and_static() { + return 0; +} + +int libshared_and_static_exported() { + return 0; +} + +int libshared_and_static_deprecated() { + return 0; +} + +int libshared_and_static_not_exported() { + return 0; +} + +int libshared_and_static_excluded() { + return 0; +} diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h new file mode 100644 index 000000000..7df769460 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h @@ -0,0 +1,58 @@ + +#ifndef SHARED_AND_STATIC_H +#define SHARED_AND_STATIC_H + +#include "libshared_and_static_export.h" + +class LIBSHARED_AND_STATIC_EXPORT LibsharedAndStatic { +public: + int libshared_and_static() const; + +#ifdef COMPILER_IS_MSVC + int libshared_and_static_exported() const; +#else + int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const; +#endif + + int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const; + + int libshared_and_static_not_exported() const; + + int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const; +}; + +class LibsharedAndStaticNotExported { +public: + int libshared_and_static() const; + + int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const; + + int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const; + + int libshared_and_static_not_exported() const; + + int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const; +}; + +class LIBSHARED_AND_STATIC_NO_EXPORT LibsharedAndStaticExcluded { +public: + int libshared_and_static() const; + + int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const; + + int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const; + + int libshared_and_static_not_exported() const; + + int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const; +}; + +LIBSHARED_AND_STATIC_EXPORT int libshared_and_static_exported(); + +LIBSHARED_AND_STATIC_DEPRECATED int libshared_and_static_deprecated(); + +int libshared_and_static_not_exported(); + +int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded(); + +#endif diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt new file mode 100644 index 000000000..2030de68b --- /dev/null +++ b/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt @@ -0,0 +1,23 @@ + +macro(shared_variant_build_pass Source Message) + build_pass("libshared_and_static.h" "shared_variant" "lib_shared_and_static" "${Source}" ${Message}) +endmacro() + +macro(shared_variant_build_fail Source Message) + build_fail("libshared_and_static.h" "shared_variant" "lib_shared_and_static" "${Source}" ${Message}) +endmacro() + +macro(static_variant_build_pass Source Message) + build_pass("libshared_and_static.h" "static_variant" "lib_shared_and_static" "${Source}" ${Message}) +endmacro() + +macro(static_variant_build_fail Source Message) + build_fail("libshared_and_static.h" "static_variant" "lib_shared_and_static" "${Source}" ${Message}) +endmacro() + +static_variant_build_pass("return libshared_and_static_exported();" "Failed to build static variant") +shared_variant_build_pass("return libshared_and_static_exported();" "Failed to build shared variant") +shared_variant_build_fail("return libshared_and_static_deprecated();" "Built shared deprecated variant") +static_variant_build_fail("return libshared_and_static_deprecated();" "Built static deprecated variant") +static_variant_build_pass("return libshared_and_static_not_exported();" "Failed to build static not exported variant") +shared_variant_build_fail("return libshared_and_static_not_exported();" "Built shared not exported variant") diff --git a/Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt new file mode 100644 index 000000000..8e4ee2b31 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt @@ -0,0 +1,6 @@ + +project(libshared) + +add_library(libshared SHARED libshared.cpp) + +generate_export_header(libshared) diff --git a/Tests/Module/GenerateExportHeader/libshared/libshared.cpp b/Tests/Module/GenerateExportHeader/libshared/libshared.cpp new file mode 100644 index 000000000..9812f5569 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libshared/libshared.cpp @@ -0,0 +1,91 @@ + +#include "libshared.h" + +int Libshared::libshared() const +{ + return 0; +} + +int Libshared::libshared_exported() const +{ + return 0; +} + +int Libshared::libshared_deprecated() const +{ + return 0; +} + +int Libshared::libshared_not_exported() const { + return 0; +} + +int Libshared::libshared_excluded() const { + return 0; +} + +int LibsharedNotExported::libshared() const +{ + return 0; +} + +int LibsharedNotExported::libshared_exported() const +{ + return 0; +} + +int LibsharedNotExported::libshared_deprecated() const +{ + return 0; +} + +int LibsharedNotExported::libshared_not_exported() const { + return 0; +} + +int LibsharedNotExported::libshared_excluded() const { + return 0; +} + +int LibsharedExcluded::libshared() const +{ + return 0; +} + +int LibsharedExcluded::libshared_exported() const +{ + return 0; +} + +int LibsharedExcluded::libshared_deprecated() const +{ + return 0; +} + +int LibsharedExcluded::libshared_not_exported() const { + return 0; +} + +int LibsharedExcluded::libshared_excluded() const { + return 0; +} + +int libshared() { + return 0; +} + +int libshared_exported() { + return 0; +} + +int libshared_deprecated() { + return 0; +} + +int libshared_not_exported() { + return 0; +} + +int libshared_excluded() { + return 0; +} \ No newline at end of file diff --git a/Tests/Module/GenerateExportHeader/libshared/libshared.h b/Tests/Module/GenerateExportHeader/libshared/libshared.h new file mode 100644 index 000000000..280e18571 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libshared/libshared.h @@ -0,0 +1,59 @@ + +#ifndef LIBSHARED_H +#define LIBSHARED_H + +#include "libshared_export.h" + +class LIBSHARED_EXPORT Libshared { +public: + int libshared() const; + +#ifdef COMPILER_IS_MSVC + // Double exporting not possible with MSVC + int libshared_exported() const; +#else + int LIBSHARED_EXPORT libshared_exported() const; +#endif + + int LIBSHARED_DEPRECATED libshared_deprecated() const; + + int libshared_not_exported() const; + + int LIBSHARED_NO_EXPORT libshared_excluded() const; +}; + +class LibsharedNotExported { +public: + int libshared() const; + + int LIBSHARED_EXPORT libshared_exported() const; + + int LIBSHARED_DEPRECATED_EXPORT libshared_deprecated() const; + + int libshared_not_exported() const; + + int LIBSHARED_NO_EXPORT libshared_excluded() const; +}; + +class LIBSHARED_NO_EXPORT LibsharedExcluded { +public: + int libshared() const; + + int LIBSHARED_EXPORT libshared_exported() const; + + int LIBSHARED_DEPRECATED_EXPORT libshared_deprecated() const; + + int libshared_not_exported() const; + + int LIBSHARED_NO_EXPORT libshared_excluded() const; +}; + +LIBSHARED_EXPORT int libshared_exported(); + +LIBSHARED_DEPRECATED_EXPORT int libshared_deprecated(); + +int libshared_not_exported(); + +int LIBSHARED_NO_EXPORT libshared_excluded(); + +#endif diff --git a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt new file mode 100644 index 000000000..7a05205b4 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt @@ -0,0 +1,27 @@ + +macro(shared_build_pass Source Message) + build_pass("libshared.h" "libshared" "libshared" "${Source}" ${Message}) +endmacro() + +macro(shared_build_fail Source Message) + build_fail("libshared.h" "libshared" "libshared" "${Source}" ${Message}) +endmacro() + +shared_build_pass("Libshared l; return l.libshared_exported();" "Failed to build exported") + +shared_build_fail("Libshared l; return l.libshared_deprecated();" "Built use of deprecated class method. This should not be possible.") +if (COMPILER_HAS_HIDDEN_VISIBILITY) + shared_build_fail("Libshared l; return l.libshared_excluded();" "Built use of excluded class method. This should not be possible.") +else() + # There is no MSVC equivalent to hiding symbols. + shared_build_pass("Libshared l; return l.libshared_excluded();" "Built use of excluded class method. This is possible on MSVC.") +endif() +shared_build_fail("LibsharedNotExported l; return l.libshared();" "Built use of not-exported class method. This should not be possible.") +shared_build_fail("LibsharedNotExported l; return l.libshared_not_exported();" "Built use of not-exported class method. This should not be possible.") +shared_build_fail("LibsharedNotExported l; return l.libshared_excluded();" "Built use of not-exported class method. This should not be possible.") +shared_build_fail("LibsharedExcluded l; return l.libshared();" "Built use of excluded class method. This should not be possible.") +shared_build_fail("LibsharedExcluded l; return l.libshared_not_exported();" "Built use of excluded class method. This should not be possible.") +shared_build_fail("LibsharedExcluded l; return l.libshared_excluded();" "Built use of excluded class method. This should not be possible.") + +shared_build_fail("return libshared_excluded();" "Built use of excluded function. This should not be possible.") +shared_build_fail("return libshared_not_exported();" "Built use of not-exported function. This should not be possible.") diff --git a/Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt new file mode 100644 index 000000000..8db182710 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt @@ -0,0 +1,8 @@ + +project(libstatic) + +# Show that the export header has no effect on a static library. + +add_library(libstatic STATIC libstatic.cpp) + +generate_export_header(libstatic) diff --git a/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp b/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp new file mode 100644 index 000000000..c8b7d4454 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp @@ -0,0 +1,87 @@ + +#include "libstatic.h" + +int Libstatic::libstatic() const +{ + return 0; +} + +int Libstatic::libstatic_exported() const +{ + return 0; +} + +int Libstatic::libstatic_deprecated() const +{ + return 0; +} + +int Libstatic::libstatic_not_exported() const { + return 0; +} + +int Libstatic::libstatic_excluded() const { + return 0; +} + +int LibstaticNotExported::libstatic() const +{ + return 0; +} + +int LibstaticNotExported::libstatic_exported() const +{ + return 0; +} + +int LibstaticNotExported::libstatic_deprecated() const +{ + return 0; +} + +int LibstaticNotExported::libstatic_not_exported() const { + return 0; +} + +int LibstaticNotExported::libstatic_excluded() const { + return 0; +} + +int LibstaticExcluded::libstatic() const +{ + return 0; +} + +int LibstaticExcluded::libstatic_exported() const +{ + return 0; +} + +int LibstaticExcluded::libstatic_deprecated() const +{ + return 0; +} + +int LibstaticExcluded::libstatic_not_exported() const { + return 0; +} + +int LibstaticExcluded::libstatic_excluded() const { + return 0; +} + +int libstatic_exported() { + return 0; +} + +int libstatic_deprecated() { + return 0; +} + +int libstatic_not_exported() { + return 0; +} + +int libstatic_excluded() { + return 0; +} \ No newline at end of file diff --git a/Tests/Module/GenerateExportHeader/libstatic/libstatic.h b/Tests/Module/GenerateExportHeader/libstatic/libstatic.h new file mode 100644 index 000000000..c6562ecb6 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libstatic/libstatic.h @@ -0,0 +1,54 @@ + +#ifndef LIBSTATIC_H +#define LIBSTATIC_H + +#include "libstatic_export.h" + +class LIBSTATIC_EXPORT Libstatic { +public: + int libstatic() const; + + int LIBSTATIC_EXPORT libstatic_exported() const; + + int LIBSTATIC_DEPRECATED libstatic_deprecated() const; + + int libstatic_not_exported() const; + + int LIBSTATIC_NO_EXPORT libstatic_excluded() const; +}; + +class LibstaticNotExported { +public: + int libstatic() const; + + int LIBSTATIC_EXPORT libstatic_exported() const; + + int LIBSTATIC_DEPRECATED libstatic_deprecated() const; + + int libstatic_not_exported() const; + + int LIBSTATIC_NO_EXPORT libstatic_excluded() const; +}; + +class LIBSTATIC_NO_EXPORT LibstaticExcluded { +public: + int libstatic() const; + + int LIBSTATIC_EXPORT libstatic_exported() const; + + int LIBSTATIC_DEPRECATED libstatic_deprecated() const; + + int libstatic_not_exported() const; + + int LIBSTATIC_NO_EXPORT libstatic_excluded() const; +}; + +LIBSTATIC_EXPORT int libstatic_exported(); + +LIBSTATIC_DEPRECATED int libstatic_deprecated(); + +int libstatic_not_exported(); + +int LIBSTATIC_NO_EXPORT libstatic_excluded(); + +#endif diff --git a/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt new file mode 100644 index 000000000..58b875a07 --- /dev/null +++ b/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt @@ -0,0 +1,13 @@ + +macro(static_build_pass Source Message) + build_pass("libstatic.h" "libstatic" "libstatic" "${Source}" ${Message}) +endmacro() + +macro(static_build_fail Source Message) + build_fail("libstatic.h" "libstatic" "libstatic" "${Source}" ${Message}) +endmacro() + +static_build_pass("Libstatic l; return l.libstatic_exported();" "Failed to build exported.") + +static_build_fail("Libstatic l; return l.libstatic_deprecated();" "Built use of deprecated class method. This should not be possible.") +static_build_fail("libstatic_deprecated();" "Built use of deprecated function. This should not be possible.")