Declarations for shared library in Windows.

Added __declspec(dllimport) and __declspec(dllexport) declarations
when compiled in Windows.
This commit is contained in:
Maciej Dems 2015-12-09 14:52:09 +01:00
parent ecd52bc610
commit c47318afa8
3 changed files with 56 additions and 29 deletions

View File

@ -94,12 +94,17 @@ if (BIICODE)
return()
endif ()
add_library(cppformat ${FMT_SOURCES})
if (BUILD_SHARED_LIBS AND UNIX AND NOT APPLE)
# Fix rpmlint warning:
# unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
target_link_libraries(cppformat -Wl,--as-needed)
endif ()
if (BUILD_SHARED_LIBS)
add_library(cppformat SHARED ${FMT_SOURCES})
if (UNIX AND NOT APPLE)
# Fix rpmlint warning:
# unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
target_link_libraries(cppformat -Wl,--as-needed)
endif ()
else ()
add_library(cppformat ${FMT_SOURCES})
endif()
if (FMT_PEDANTIC AND
(CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")))
set(FMT_EXTRA_COMPILE_FLAGS "-Wall -Wextra -Wshadow -pedantic")
@ -114,6 +119,10 @@ if (CPP11_FLAG AND FMT_PEDANTIC)
set(FMT_TEST_DEFAULT_FLAGS TRUE)
endif ()
if (BUILD_SHARED_LIBS)
set(FMT_EXTRA_COMPILE_FLAGS "${FMT_EXTRA_COMPILE_FLAGS} -DFMT_EXPORT")
endif ()
set_target_properties(cppformat
PROPERTIES COMPILE_FLAGS "${FMT_EXTRA_COMPILE_FLAGS}")

View File

@ -64,6 +64,18 @@ typedef long long intmax_t;
# include <iterator>
#endif
#if !defined(FMT_HEADER_ONLY) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
# ifdef FMT_EXPORT
# define FMT_API __declspec(dllexport)
# elif defined(FMT_SHARED)
# define FMT_API __declspec(dllimport)
# else
# define FMT_API
# endif
#else
# define FMT_API
#endif
#ifdef _MSC_VER
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
@ -676,7 +688,7 @@ class FixedBuffer : public fmt::Buffer<Char> {
FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {}
protected:
void grow(std::size_t size);
FMT_API void grow(std::size_t size);
};
template <typename Char>
@ -704,7 +716,7 @@ class CharTraits<char> : public BasicCharTraits<char> {
// Formats a floating-point number.
template <typename T>
static int format_float(char *buffer, std::size_t size,
FMT_API static int format_float(char *buffer, std::size_t size,
const char *format, unsigned width, int precision, T value);
};
@ -715,7 +727,7 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
static wchar_t convert(wchar_t value) { return value; }
template <typename T>
static int format_float(wchar_t *buffer, std::size_t size,
FMT_API static int format_float(wchar_t *buffer, std::size_t size,
const wchar_t *format, unsigned width, int precision, T value);
};
@ -769,12 +781,12 @@ FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
void report_unknown_type(char code, const char *type);
FMT_API void report_unknown_type(char code, const char *type);
// Static data is placed in this class template to allow header-only
// configuration.
template <typename T = void>
struct BasicData {
struct FMT_API BasicData {
static const uint32_t POWERS_OF_10_32[];
static const uint64_t POWERS_OF_10_64[];
static const char DIGITS[];
@ -863,7 +875,7 @@ class UTF8ToUTF16 {
MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_;
public:
explicit UTF8ToUTF16(StringRef s);
FMT_API explicit UTF8ToUTF16(StringRef s);
operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const wchar_t *c_str() const { return &buffer_[0]; }
@ -878,7 +890,7 @@ class UTF16ToUTF8 {
public:
UTF16ToUTF8() {}
explicit UTF16ToUTF8(WStringRef s);
FMT_API explicit UTF16ToUTF8(WStringRef s);
operator StringRef() const { return StringRef(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const char *c_str() const { return &buffer_[0]; }
@ -887,15 +899,15 @@ class UTF16ToUTF8 {
// Performs conversion returning a system error code instead of
// throwing exception on conversion error. This method may still throw
// in case of memory allocation error.
int convert(WStringRef s);
FMT_API int convert(WStringRef s);
};
void format_windows_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT;
FMT_API void format_windows_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT;
#endif
void format_system_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT;
FMT_API void format_system_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT;
// A formatting argument value.
struct Value {
@ -1638,7 +1650,7 @@ class ArgMap {
MapType map_;
public:
void init(const ArgList &args);
FMT_API void init(const ArgList &args);
const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
typename MapType::const_iterator it = map_.find(name);
@ -1768,7 +1780,7 @@ class FormatterBase {
int next_arg_index_;
// Returns the argument with specified index.
Arg do_get_arg(unsigned arg_index, const char *&error);
FMT_API Arg do_get_arg(unsigned arg_index, const char *&error);
protected:
const ArgList &args() const { return args_; }
@ -1824,7 +1836,7 @@ class PrintfFormatter : private FormatterBase {
public:
explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {}
void format(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str);
FMT_API void format(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str);
};
} // namespace internal
@ -2929,14 +2941,14 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
// Reports a system error without throwing an exception.
// Can be used to report errors from destructors.
void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
FMT_API void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
#if FMT_USE_WINDOWS_H
/** A Windows error. */
class WindowsError : public SystemError {
private:
void init(int error_code, CStringRef format_str, ArgList args);
FMT_API void init(int error_code, CStringRef format_str, ArgList args);
public:
/**
@ -2975,7 +2987,7 @@ class WindowsError : public SystemError {
// Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors.
void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
FMT_API void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
#endif
@ -2987,7 +2999,7 @@ enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
Example:
print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23);
*/
void print_colored(Color c, CStringRef format, ArgList args);
FMT_API void print_colored(Color c, CStringRef format, ArgList args);
/**
\rst
@ -3019,7 +3031,7 @@ inline std::wstring format(WCStringRef format_str, ArgList args) {
print(stderr, "Don't {}!", "panic");
\endrst
*/
void print(std::FILE *f, CStringRef format_str, ArgList args);
FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args);
/**
\rst
@ -3030,7 +3042,7 @@ void print(std::FILE *f, CStringRef format_str, ArgList args);
print("Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
void print(CStringRef format_str, ArgList args);
FMT_API void print(CStringRef format_str, ArgList args);
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
@ -3067,7 +3079,7 @@ inline std::wstring sprintf(WCStringRef format, ArgList args) {
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
int fprintf(std::FILE *f, CStringRef format, ArgList args);
FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
/**
\rst
@ -3362,7 +3374,7 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
print(cerr, "Don't {}!", "panic");
\endrst
*/
void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
#endif

View File

@ -2,6 +2,10 @@ set(FMT_GMOCK_DIR ../gmock)
include_directories(.. ${FMT_GMOCK_DIR})
if (BUILD_SHARED_LIBS)
set(FMT_IMPORT "-DFMT_SHARED")
endif ()
# We compile Google Test ourselves instead of using pre-compiled libraries.
# See the Google Test FAQ "Why is it not recommended to install a
# pre-compiled copy of Google Test (for example, into /usr/local)?"
@ -45,6 +49,7 @@ endif ()
set(TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc)
add_library(test-main STATIC ${TEST_MAIN_SRC})
set_target_properties(test-main PROPERTIES COMPILE_FLAGS "${FMT_IMPORT}")
target_link_libraries(test-main cppformat gmock)
# Adds a test.
@ -54,6 +59,7 @@ function(add_fmt_test name)
add_executable(${name} ${name}.cc ${add_fmt_test_UNPARSED_ARGUMENTS})
target_link_libraries(${name} test-main)
if (NOT add_fmt_test_CUSTOM_LINK)
set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${FMT_IMPORT}")
target_link_libraries(${name} cppformat)
endif ()
add_test(NAME ${name} COMMAND ${name})