Make FMT_API symbols use the default visibility on non-Windows
platforms. Otherwise, one cannot use the generated fmt library when
compiling globally with -fvisibility=hidden.
Fixes compile errors like:
```
../3rdParty/fmt/include/fmt/core.h:757: error: undefined reference to 'fmt::v6::internal::assert_fail(char const*, int, char const*)'
```
Note that the symbol exists, but is local:
```
$ nm -C libfmtd.so.6.1.3 | grep assert_fail
U __assert_fail
0000000000233ffa t fmt::v6::internal::assert_fail(char const*, int, char const*)
```
With this patch, the compile error is gone and the symbol is properly
exported:
```
$ nm -a bin/libfmtd.so -C | grep assert_fail
U __assert_fail
00000000002366ba T fmt::v6::internal::assert_fail(char const*, int, char const*)
```
Change-Id: I96054e622d9a2ae81907e1b01a1033e629767a91
## Problem
In the case of an existing `fmt` namespace (in my project this looks like `Project::fmt`) it is possible to get a namespace clash in debug builds (MSVC 2017)
## Proposed Solution
When referencing `fmt` internally, be explicit that it is relative to the global namespace using `::fmt`
The nvcc compiler (at least up to 9.2) defines `__SIZEOF_INT128__`, but doesn't support 128-bit integers on device code:
```
error: "fmt::v6::format_arg_store<fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer<char>>, char>, const char *, int, const char *>" contains a 128-bit integer, which is not supported in device code
```
The `std::is_base_of<T,U>()` and `std::is_reference<T>()` member functions were added in C++14. To maintain C++11 compatibility, use the `::value` instead.
Current code fails on intel-17 and other compilers if using strict C++11
Similar to the MSC Compiler, the NVidia NVCC compiler also
emits unreachable code warnings when there is a return
statement following an exception. These changes eliminate
those warnings.
* Squelch MSVC warning exporting subclasses of runtime_error
When compiling {fmt} as a DLL, MSVC complains that we are exporting
classes that inherit from "std::runtime_error", which we are not
exporting.
In this case, it's not really a problem because that symbol is already
exported via the C++ stdlib. So we just add a pragma to silence the
warning.
* Fix compilation with MinGW
Commit 3bc28fcc6b ("Squelch MSVC warning exporting subclasses of
runtime_error", 2019-11-29) silenced a MSVC warning under. The MinGW
compiler also defines _WIN32, but does not support the "warning" pragma.
Introduce a helper macro to squelch the MSVC warning only when using the
Microsoft compiler.
Signed-off-by: Beat Bolli <dev@drbeat.li>
* Fix compilation with VS2015 (#1450)
VS2015 does not support the __pragma(...) syntax in the midst of a
class declaration, so move it to just before the declaration.
Commit 3bc28fcc6b ("Squelch MSVC warning exporting subclasses of
runtime_error", 2019-11-29) silenced a MSVC warning under. The MinGW
compiler also defines _WIN32, but does not support the "warning" pragma.
Introduce a helper macro to squelch the MSVC warning only when using the
Microsoft compiler.
Signed-off-by: Beat Bolli <dev@drbeat.li>
When compiling {fmt} as a DLL, MSVC complains that we are exporting
classes that inherit from "std::runtime_error", which we are not
exporting.
In this case, it's not really a problem because that symbol is already
exported via the C++ stdlib. So we just add a pragma to silence the
warning.
If you compile using `nvcc` and pass the option `--expt-relaxed-constexpr` it will crash with an internal compiler error. This modification prevents using `constexpr` in `fmtlib` when compiling using `nvcc` and prevents the crash.
test cuda: import fmt in CUDA source code
Current test is only for Windows(cl.exe).
Need to test more with the other host compilers...
* Activate the test when `find_package(CUDA)` worked
* The test runs with C++14
Detailed comments in 'test/cuda-test'
test cuda: add more comment / macro check
* checks both `__NVCC__` and `__CUDACC__`
More comments for CMake and CUDA source file.
test cuda: <fmt/core.h> checks NVCC and CUDA
The header file checks 2 things.
* __NVCC__: if the compiler is from NVIDIA
* __CUDACC__: if the source code is CUDA(.cu) file
Since we can't sure all users prefer latest, Version for
`find_pacakge(CUDA)` is downgraded to 9.0.
This is the minimum version for C++14 in CUDA
QtCreator (4.9) Clang Code Model (Clang 7) gives the
warning:core.h:404:11: error: an attribute list cannot appear here
core.h:116:24: note: expanded from macro 'FMT_NORETURN'
* Update format.cc
As the explicit instantiation *declaration* of `internal::basic_data<void>` in format.h, this explicit instantiation *definition* should mirror FMT_API also.
* Mirror visibility of explicit instantiation declaration
explicit instantiation declaration of internal::basic_data<void> should mirror visibility of FMT_API
* Eliminate `__declspec(dllexport)` designation on extern template internal::basic_data<> when `extern` affected during exporting phase.
* Add `FMT_EXTERN_TEMPLATE_API` for designate DLL export `extern template`
When exporting DLL, do not designate `__declspec(dllexport)` any template that has any explicit class template declaration a.k.a. `extern template`. Instead, designate `__declspec(dllexport)` at single point where we have explicit class template definition a.k.a. normal instantiation without `extern`
Note: this is a c++11 feature.
* Delete whole `FMT_USE_EXTERN_TEMPLATES` block and its condition
1. Remove whole `FMT_USE_EXTERN_TEMPLATES` block
(trailing `FMT_UDL_TEMPLATE` block)
````
#ifndef FMT_USE_EXTERN_TEMPLATES
# ifndef FMT_HEADER_ONLY
# define FMT_USE_EXTERN_TEMPLATES \
((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \
(FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
# else
# define FMT_USE_EXTERN_TEMPLATES 0
# endif
#endif
````
2. Delete `FMT_USE_EXTERN_TEMPLATES` condition, only condition, that trailing basic_data class template definition.
````
#if FMT_USE_EXTERN_TEMPLATES
extern template struct basic_data<void>;
#endif
````
3. Replace `FMT_API` with new `FMT_EXTERN_TEMPLATE_API` added in `core.h` for sake of extern template of `basic_data<void>`
* Add `#define FMT_EXTERN extern` only when not `FMT_HEADER_ONLY`
* Replace `extern` on basic_data<void> with the `FMT_EXTERN` condition in core.h
* replace misspelled if !define() with ifndef