Coder Social home page Coder Social logo

cginternals / cmake-init Goto Github PK

View Code? Open in Web Editor NEW
904.0 40.0 116.0 2.4 MB

Template for reliable, cross-platform C++ project setup using cmake.

License: MIT License

CMake 66.22% C++ 5.04% C 24.88% Makefile 2.51% Dockerfile 1.35%
c-plus-plus cmake template c-plus-plus-11

cmake-init's Introduction


The C++ CMake Project Template

Travis Appveyor Tokei Setup Guide

cmake-init is a sophisticated copy & paste template for modern C and C++ projects. The main goals include support of all use cases around software development (programming, testing, Q&A, deployment, documentation) while being modular, flexible, and idiomatic. cmake-init is therefore a collection of cmake best-practices.

The main target platforms are typical desktop, laptop, and server platforms. Currently supported are:

  • Windows
  • macOS
  • GNU/Linux

However, other UNIX versions may work as well if they are supported by CMake.

The cmake-init template assumes you want to setup a project using

  • CMake (3.0 or above)
  • C/C++ compiler

Contents

Usage

The intended use of the template is a copy of the current version with a subsequent replacement of project names and customization of modules to your needs. This is documented within the adaption guide. Another approach is the initialization of a new CMake project where the required features are adopted from cmake-init. We propose the former workflow.

Concluding, a new project should contain the core modules and, as needed, add the maintainer and development modules as required. All modules are designed in a way that they can be excluded. The process of integration or removal of a module/feature is documented with each module.

Adaption Guide

The file ADAPT.md contains a task checklist for new projects. Your start with a copy of cmake-init and process each item from the checklist, adjusting the template to your needs.

Update

After some time working on a project, cmake-init may be updated and you want to integrate the changes. For an overview of changes we suggest to use the cmake-init Template Check module. Alternatively, you can update the required modules selectively.

Non-Goals

In order to be usable in a deterministic, idiomatic fashion, cmake-init avoids the following approaches and features:

Super-Build

Due to the current semantics of targets and CMake internals, combining multiple cmake-init projects into one super-build project is not officially supported. There are limited and restricting workarounds. Actual solution: treat each project separately and use explicit dependency management.

High Abstraction

We use low abstractions to not build a language upon CMake a user has to learn.

File Glob

Explicit source specification prevents erroneous cases when adding and removing sources from the project tree.

Module Documentation

Core Modules

CMake Initialization

As with most CMake projects, cmake-init initializes the CMake environment. This includes the minimum required CMake version,

# CMake version
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

required policies,

# Set policies
set_policy(CMP0054 NEW) # ENABLE CMP0054: Only interpret if() arguments as variables or keywords when unquoted.
set_policy(CMP0042 NEW) # ENABLE CMP0042: MACOSX_RPATH is enabled by default.
set_policy(CMP0063 NEW) # ENABLE CMP0063: Honor visibility properties for all target types.

adaption of the cmake module path,

# Include cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

and an include of default modules that are typically required for each project.

include(GenerateExportHeader)
include(WriteCompilerDetectionHeader)

CMake Backward Compatibility

As some modules as WriteCompilerDetectionHeader may not be available, cmake-init suggests to use fallbacks and availability detection.

Using this example, the module include

include(WriteCompilerDetectionHeader)

is replaced by

set(WriterCompilerDetectionHeaderFound NOTFOUND)
# This module is only available with CMake >=3.1, so check whether it could be found
# BUT in CMake 3.1 this module doesn't recognize AppleClang as compiler, so just use it as of CMake 3.2
if (${CMAKE_VERSION} VERSION_GREATER "3.2")
    include(WriteCompilerDetectionHeader OPTIONAL RESULT_VARIABLE WriterCompilerDetectionHeaderFound)
endif()

and the result can be later used with

if (WriterCompilerDetectionHeaderFound)
  # ...
endif ()

Another issue with older CMake versions is the unavailability of then-unpublished language standards (e.g., C++11 and CMake 3.0). For those versions, the compile options has to be extended manually.

For new projects, we suggest to require at least CMake 3.2 and to therefore adjust the minimum required version:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

Project Meta Information

The declaration of project-wide information--that are used, e.g., within documentation, testing, and deployment--, is combined within the project meta information section in the main CMakeLists.txt.

#
# Project description and (meta) information
#

# Meta information about the project
set(META_PROJECT_NAME        "template")
set(META_PROJECT_DESCRIPTION "CMake Project Template")
set(META_AUTHOR_ORGANIZATION "CG Internals GmbH")
set(META_AUTHOR_DOMAIN       "https://github.com/cginternals/cmake-init/")
set(META_AUTHOR_MAINTAINER   "[email protected]")
set(META_VERSION_MAJOR       "2")
set(META_VERSION_MINOR       "0")
set(META_VERSION_PATCH       "0")
set(META_VERSION_REVISION    "<REVISION>")
set(META_VERSION             "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
set(META_NAME_VERSION        "${META_PROJECT_NAME} v${META_VERSION} (${META_VERSION_REVISION})")
set(META_CMAKE_INIT_SHA      "<CMAKE_INIT_REVISION>")

string(MAKE_C_IDENTIFIER ${META_PROJECT_NAME} META_PROJECT_ID)
string(TOUPPER ${META_PROJECT_ID} META_PROJECT_ID)

cmake-init supports the projects name, description, organization, domain, and maintainer email as well as detailed version information. For the version, we suggest to use semantic versioning. Depending on your version control system, you may want to integrate the current revision of the software as well: see Version Control System Integration. If you use the cmake-init Template Check module, the cmake-init SHA is declared within this section, too.

Last, cmake-init derives a project ID that complies with the naming schemes of C to be used within auto-generated and derived source code content (e.g., macro identifiers).

Project Meta Information Code Generation

The result of this module is the generation of a C header file that propagates the project meta information to your C and C++ projects. For this, the CMake file configuration feature is used on the version.h.in header template.

#define @META_PROJECT_ID@_PROJECT_NAME        "@META_PROJECT_NAME@"
#define @META_PROJECT_ID@_PROJECT_DESCRIPTION "@META_PROJECT_DESCRIPTION@"

#define @META_PROJECT_ID@_AUTHOR_ORGANIZATION "@META_AUTHOR_ORGANIZATION@"
#define @META_PROJECT_ID@_AUTHOR_DOMAIN       "@META_AUTHOR_DOMAIN@"
#define @META_PROJECT_ID@_AUTHOR_MAINTAINER   "@META_AUTHOR_MAINTAINER@"

#define @META_PROJECT_ID@_VERSION_MAJOR       "@META_VERSION_MAJOR@"
#define @META_PROJECT_ID@_VERSION_MINOR       "@META_VERSION_MINOR@"
#define @META_PROJECT_ID@_VERSION_PATCH       "@META_VERSION_PATCH@"
#define @META_PROJECT_ID@_VERSION_REVISION    "@META_VERSION_REVISION@"

#define @META_PROJECT_ID@_VERSION             "@META_VERSION@"
#define @META_PROJECT_ID@_NAME_VERSION        "@META_NAME_VERSION@"

The template file is configured with the project meta information and the result is stored within the build directory. Beware that this header is stored in a path derived from your project name. You should adopt this as required.

# Generate version-header
configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME}/${META_PROJECT_NAME}-version.h)

We suggest to deploy this header disregarding its internal or even public use.

#
# Deployment
#

# Deploy generated headers
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME} DESTINATION include COMPONENT dev)

Project Build Options

Maintainer Modules

cmake-init Template Check

This module allows to check the actuality of the used cmake-init template for own projects. This module is usable when the following is integrated into the CMakeLists.txt.

# Add cmake-init template check cmake targets
add_check_template_target(<CMAKE_INIT_SHA>)

Here, the <CMAKE_INIT_SHA> contains the git hash of the used cmake-init template. Further, the files cmake/HealthCheck.cmake and cmake/CheckTemplate.cmake are required.

The hash is usually configured using

# Meta information about the project
set(META_CMAKE_INIT_SHA      "<CMAKE_INIT_SHA>")

# Add cmake-init template check cmake targets
add_check_template_target(<CMAKE_INIT_SHA>)

Correctly configures, this module adds a cmake build target named check-template that compares the passed <CMAKE_INIT_SHA> with the current master commit hash of this repository and provides a link for a diff view.

Development Modules

Version Control System Integration

# Get git revision
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
string(SUBSTRING "${GIT_SHA1}" 0 12 GIT_REV)
if(NOT GIT_SHA1)
    set(GIT_REV "0")
endif()

Build Targets

Documentation

Tests

Tests are available using the Google testing frameworks googletest and googlemock. cmake-init assumes an external installment of both frameworks. Typically, package managers of each system provides a sufficient installment. For example, on Ubuntu you can install the libgmock-dev package. On macOS using Homebrew, this package is named `googletest

Linter

Continuous Integration

Deployment

Packaging

Run-time Assets

cmake-init's People

Contributors

0xb8 avatar bwasty avatar cgcostume avatar chistopher avatar cmfcmf avatar falsecam avatar felerius avatar jcfr avatar jopyth avatar kateyy avatar mjendruk avatar osechet avatar patdhlk avatar scheibel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmake-init's Issues

Compiler AppleClang not recognized

On Windows 10, CMake 3.1.3 there is an error when configuring projects using the WriterCompilerDetectionHeaderFound feature that AppleClang is not found.

Maybe the compiler was not handled in the module as of 3.1.3 and support for AppleClang was added in later versions.

CMake Warning: Policy CMP0054 is not set

Output using CMake 3.6.1.:

Lib baselib
Lib fiblib
Example fibcmd
Example fibgui
CMake Warning (dev) at cmake/CompileOptions.cmake:52 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "MSVC" will no longer be dereferenced when the policy
  is set to NEW.  Since the policy is not set the OLD behavior will be used.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:17 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/CompileOptions.cmake:67 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "MSVC" will no longer be dereferenced when the policy
  is set to NEW.  Since the policy is not set the OLD behavior will be used.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:17 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/CompileOptions.cmake:94 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "MSVC" will no longer be dereferenced when the policy
  is set to NEW.  Since the policy is not set the OLD behavior will be used.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:17 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/CompileOptions.cmake:144 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "MSVC" will no longer be dereferenced when the policy
  is set to NEW.  Since the policy is not set the OLD behavior will be used.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:17 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

Test fiblib-test
Configuring done

Add package version file

Add ability to request minimum version of cmake-init base-projects in find_package.
The CMake documentation suggests to generate and deploy a Package Version File. Besides template-config.cmake, projects would than also deploy template-config-version.cmake and allow to be included via calls like find_package(template_foo 2.0 REQUIRED).

As far as I can see, there is currently no way for users to check in CMake for versions of cmake-init-based projects, which is quite unfortunate.

Platform MSVC: /GL flag slows down debug build

The /GL compiler flag (whole program optimization) is enabled in debug and release build. This also enables link time code generation (/LTCG linker flag) in debug build, slowing down the build process. Here an example, the build time of libzeug (without examples) on a testing machine:

  • 1:56 with /GL enabled
  • 1:06 without

This flag could be disabled using cmake generators, somehow like that:

set(WIN32_COMPILE_FLAGS
    /commonflags
    $<$<CONFIG:Debug>: /debugflags... >
    $<$<CONFIG:Release>: /releaseflags... >)

I think you don't need link time optimization in debug build, fast developing and testing is more important there. Anyway, the template should provide a possibility to set compiler flags per build type.

GetGitRevisionDescription fails on new repository (before push)

When trying to build a project in a new git repository, before the first push, some git directories are not yet set up and the GetGitRevisionDescription.cmake script fails. The script should check if directories exist before trying to access them.

CMake Error: File /workspace/projects/cginternals/cppfs/.git/packed-refs does not exist.

CMake Error at build/CMakeFiles/git-data/grabRef.cmake:27 (configure_file):
configure_file Problem configuring file
Call Stack (most recent call first):
cmake/GetGitRevisionDescription.cmake:77 (include)
CMakeLists.txt:37 (get_git_head_revision)

CMake Error at build/CMakeFiles/git-data/grabRef.cmake:28 (file):
file failed to open for reading (No such file or directory):
/workspace/projects/cginternals/cppfs/build/CMakeFiles/git-data/packed-refs
Call Stack (most recent call first):
cmake/GetGitRevisionDescription.cmake:77 (include)
CMakeLists.txt:37 (get_git_head_revision)

CMake Error at build/CMakeFiles/git-data/grabRef.cmake:39 (file):
file failed to open for reading (No such file or directory):
/workspace/projects/cginternals/cppfs/build/CMakeFiles/git-data/head-ref
Call Stack (most recent call first):
cmake/GetGitRevisionDescription.cmake:77 (include)
CMakeLists.txt:37 (get_git_head_revision)

project adaption adjustments

manual not mentioned in ADAPT
ADAPT line 37-41 wrong
source/codegeneration not mentioned in ADAPT
api-docs/CMakeLists adjust depends in line 51
check-targets are present if neither cppcheck or clang-tidy is installed
docs target is present if neither docs or manual are build
to travis.yaml add chmod +x configure to avoid permission error if repo was initialized on windows

make clear that cppcheck, doxygen, clang-tidy must be installed to generate specific targets

Handle deprecation of CMP0037

CMake 3.13 issues the following warning:

CMake Deprecation Warning at cmake/Custom.cmake:6 (cmake_policy):
  The OLD behavior for policy CMP0037 will be removed from a future version
  of CMake.

  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:19 (set_policy)

The immediate impact for cmake-init may be the usage of the registered target name test which cannot be used anymore once the policy is removed.
I suggest to use another target name or attach to the then-registered test-target.

Adhere to FreeBSD defaults

In glbinding, @murashin opened a PR added usr/local/include as default include path for FreeBSD (cginternals/glbinding#241). Upon research, I found the usr/local prefix to be the default directory for non-system libraries (source: https://www.freebsd.org/doc/handbook/dirstructure.html). I suggest we adapt this default include path (and probably linker path, too?) for FreeBSD and probably other Unix-based systems.

Furthermore, there may be other FreeBSD default we want to consider.

Deployment

  • Add function to collect and install dependencies
  • Create app-bundles on macOS
  • Use Fixup_Bundle

Use target_link_options to pass linker options

As of CMake 3.13, the previously missing function target_link_options was introduced. I suggest to use this instead of target_link_libraries. The current implementation does not allow passing linker options for MSVC.

Details:
Options (and linker options, too) start with a front slash for MSVC (e.g., /LTCG). As we use target_link_libraries to pass this option to the linker, CMake assumes library names to link against and gracefully converts our Unix-encoded path separator to Windows-encoded path separators, resulting in \LTCG being passed to the linker.

Option to generate cppcheck reports as xml file

It would be nice to have an option to generate ccpcheck reports as an xml file. When calling cppcheck, using the --xml --output-file=<output_file> arguments forces cppcheck to output its report to the given file.

Higher Priority of System Includes using XCode [Mac]

Using XCode (5.+) the system includes (/usr/include) are used instead of the project's includes. The solution is to prepend the project includes as follows (using the CMake include_directories () command):

include_directories (BEFORE ...)

Bug Report: Separator Issue in .localconfig/default

in file .localconfig/default

export CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:D:/cmake-init-master/thirdparty/qt5"

this does not work in windows got error running ./configure debug


I change separator from : to ;

export CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};D:/cmake-init-master/thirdparty/qt5"

It works !

Don't use macros in template-config.cmake

Using macros in config scripts is problematic because macros in cmake don't get their own variable scope:

Note that if you have a variable with the same name in the scope from which the macro is called, using unreferenced names will use the existing variable instead of the arguments.

(http://www.cmake.org/cmake/help/v3.0/command/macro.html)

Now, if a project just so happens to use LIBNAME instead of target to define a target name and includes a cmake-init based library, the library's config-script will silently change the target name (!).

Small "adapt" improvement

To simplify the "adapt" operation:

  • in deploy/CMakeLists.txt, replace include(packages/pack-template.cmake) with include(packages/pack-${META_PROJECT_NAME}.cmake)
  • Remove the corresponding line from ADAPT.md

Missing LATEX_COMPILER and LaTeX

Hi guys,

$ ./configure debug
Configuring ...
-- Selecting Windows SDK version 10.0.17134.0 to target Windows 10.0.14393.
-- Could NOT find cppcheck (missing: cppcheck_EXECUTABLE)
-- Check cppcheck skipped: cppcheck not found
-- Could NOT find clang_tidy (missing: clang_tidy_EXECUTABLE)
-- Check clang-tidy skipped: clang-tidy not found
-- Lib baselib
-- Lib fiblib
-- Example fibcmd
-- Example fibgui

CMake Deprecation Warning at cmake/Custom.cmake:6 (cmake_policy):
  The OLD behavior for policy CMP0037 will be removed from a future version
  of CMake.
  The cmake-policies(7) manual explains that the OLD behaviors of all
  policies are deprecated and that a policy should be set to OLD only under
  specific short-term circumstances.  Projects should be ported to the NEW
  behavior and not rely on setting a policy to OLD.
Call Stack (most recent call first):
  source/tests/CMakeLists.txt:19 (set_policy)

-- Test fiblib-test
-- Doc api-docs
-- Could NOT find LATEX (missing: LATEX_COMPILER)
-- Disabled generation of documentation (missing LaTeX).
-- Configuring done
-- Generating done
-- Build files have been written to: D:/cmake-init-master/build-debug

Project configured. To build the project, use

  cmake --build build-debug

I have installed MikeTex but still got the same mising.
Help needed.

Thanks.

What's the problem with gtest/mingw?

if(OPTION_BUILD_TESTS AND NOT MINGW)

Does anyone know/remember, why testing with gtest on mingw fails? I uncommented this and got strange cmake errors, I gues this is why it is disabled. But can't find the issue or bug regarding ctest. Can we fix this somehow to enable testing on Windows with mingw?

Update GetGitRevisionDescription.cmake and GetGitRevisionDescription.cmake.in

Hi I have one cmake-init project as submodule in another project.
I have got following error:

CMake Error at build/confdesc/CMakeFiles/git-data/grabRef.cmake:36 (file):
file failed to open for reading (No such file or directory):

/home/.../workspace/hyphaframework/build/confdesc/CMakeFiles/git-data/head-ref

Call Stack (most recent call first):
confdesc/cmake/GetGitRevisionDescription.cmake:79 (include)
confdesc/CMakeLists.txt:35 (get_git_head_revision)

I could fix it by replacing GetGitRevisionDescription.cmake and GetGitRevisionDescription.cmake.in from https://github.com/rpavlik/cmake-modules

`CMAKE_BUILD_TYPE` Ignored by XCode Generator [MacOS]

Hi,

recently I encountered that the CMake XCode generator ignores the CMAK_BUILD_TYPE variable. Instead, the XCode generator uses the first value from the CMAKE_CONFIGURATION_TYPES list as the build type. This seems to be a known issue (cf. http://www.cmake.org/pipermail/cmake/2006-December/012288.html).

A possible solution ist to re-define the CMAKE_CONFIGURATION_TYPES variable in the PlatformMacOS.cmake module based on the value (set by the user) in CMAKE_BUILD_TYPE as follows:

...
if (CMAKE_BUILD_TYPE EQUALS "Release")
    set(CMAKE_CONFIGURATION_TYPES "Release")
endif()
...

I'm going to test this and supply a pull request shortly.

NSIS package generation fails when OPTION_BUILD_EXAMPLES is disabled

I haven't quite figured out what the problem is, but it has something to do with NSIS trying to modify the non-existing "examples" component. See NSIS log below

!insertmacro: Deselect_required_by_runtime

SectionGetFlags: 0->$0

IntOp: $1=1~

IntOp: $0=$0&$1

SectionSetFlags: 0->$0

IntOp: $dev_selected=0+0

warning: unknown variable/constant "{examples}" detected, ignoring (macro:Deselect_required_by_runtime:6)

SectionGetFlags: ${examples}->$0

IntOp: $1=1~

IntOp: $0=$0&$1

warning: unknown variable/constant "{examples}" detected, ignoring (macro:Deselect_required_by_runtime:9)

SectionSetFlags: ${examples}->$0

Usage: IntOp $(user_var: result) val1 OP [val2]

    OP=(+ - * / % | & ^ ~ ! || && << >>)

Error in macro Deselect_required_by_runtime on macroline 10

Error in macro MaybeSelectionChanged on macroline 10

Error in macro SectionList on macroline 4

Error in script "D:/projects/glheadless/build/_CPack_Packages/win64/NSIS/project.nsi" on line 881 -- aborting creation process

Handle app bundle deployment for macOS

Interesting cases:

  • configurability between console/plain applications and applications in app bundles
  • handling of the data directory for run-time data (for builds taken from the source, for packages/deployed bundles the data directory within the bundle)

Set CXX_VISIBILITY_PRESET to "default" for AppleClang

AppleClang (and clang?) handles RTTI for template instantiations a little different than MSVC and GCC:
With visibility "hidden", a template instantiation in library A is a different type than the exact same template instantiation in library B that links against A. That means, that dynamic_casts between those types fail with AppleClang, but not with MSVC or GCC. With visibility "default", it works.

An example is the gloperate::Loader<T>. During component registration, e.g., gloperate::Loader<Texture> is instantiated within the gloperate-qt-loaders plugin (soon to be gloperate-qt). Loader objects created by the ResourceManager have this type. When an application then calls ResourceManager::load<Texture>, gloperate::Loader<Texture> is instantiated again within the application. As both are different types according to AppleClangs RTTI, the dynamic_cast used to find a loader of the correct type always fails.

A "clean" solution might be to explicitly export all those template instantiations; however, (I think) @scheibel and I both tried it and could not get it to work. Until someone actually manages that, I propose to set the cmake CXX_VISIBILITY_PRESET to "default" for AppleClang, as this is a very subtle bug that is hard to find.

Does anybody know, whether this affects clang as well?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.