8000 Fix EXPORTS macros for building static library on windows. · gianricardo/docopt.cpp@f84c6f4 · GitHub
[go: up one dir, main page]

Skip to content

Commit f84c6f4

Browse files
committed
Fix EXPORTS macros for building static library on windows.
1 parent b8710d7 commit f84c6f4

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

CMakeLists.txt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,18 @@ set(docopt_HEADERS
3939
#============================================================================
4040
# Compile targets
4141
#============================================================================
42-
if(XCODE)
42+
if(MSVC OR XCODE)
43+
# MSVC requires __declspec() attributes, which are achieved via the
44+
# DOCOPT_DLL and DOCOPT_EXPORTS macros below. Since those macros are only
45+
# defined when building a shared library, we must build the shared and
46+
# static libraries completely separately.
4347
# Xcode does not support libraries with only object files as sources.
4448
# See https://cmake.org/cmake/help/v3.0/command/add_library.html?highlight=add_library
4549
add_library(docopt SHARED ${docopt_SOURCES} ${docopt_HEADERS})
4650
add_library(docopt_s STATIC ${docopt_SOURCES} ${docopt_HEADERS})
4751
else()
48-
# If not using Xcode, we will create an intermediate object target to avoid
49-
# compiling the source code twice.
52+
# If not using MSVC or Xcode, we will create an intermediate object target
53+
# to avoid compiling the source code twice.
5054
add_library(docopt_o OBJECT ${docopt_SOURCES} ${docopt_HEADERS})
5155
set_target_properties(docopt_o PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
5256

@@ -57,6 +61,15 @@ endif()
5761
target_include_directories(docopt PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/docopt>)
5862
target_include_directories(docopt_s PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include/docopt>)
5963

64+
if(MSVC)
65+
# DOCOPT_DLL: Must be specified when building *and* when using the DLL.
66+
# That's what the "PUBLIC" means.
67+
# DOCOPT_EXPORTS: Must use __declspec(dllexport) when building the DLL.
68+
# "PRIVATE" means it's only defined when building the DLL.
69+
target_compile_definitions(docopt PUBLIC DOCOPT_DLL
70+
PRIVATE DOCOPT_EXPORTS)
71+
endif()
72+
6073
if(NOT MSVC)
6174
set_target_properties(docopt PROPERTIES OUTPUT_NAME docopt)
6275
set_target_properties(docopt_s PROPERTIES OUTPUT_NAME docopt)

docopt.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,28 @@
1616
#include <string>
1717

1818
#ifdef DOCOPT_HEADER_ONLY
19-
#define DOCOPT_INLINE inline
19+
#define DOCOPT_INLINE inline
20+
#define DOCOPT_API
2021
#else
21-
#define DOCOPT_INLINE
22+
#define DOCOPT_INLINE
23+
24+
// With Microsoft Visual Studio, export certain symbols so they
25+
// are available to users of docopt.dll (shared library). The DOCOPT_DLL
26+
// macro should be defined if building a DLL (with Visual Studio),
27+
// and by clients using the DLL. The CMakeLists.txt and the
28+
// docopt-config.cmake it generates handle this.
29+
#ifdef DOCOPT_DLL
30+
// Whoever is *building* the DLL should define DOCOPT_EXPORTS.
31+
// The CMakeLists.txt that comes with docopt does this.
32+
// Clients of docopt.dll should NOT define DOCOPT_EXPORTS.
33+
#ifdef DOCOPT_EXPORTS
34+
#define DOCOPT_API __declspec(dllexport)
35+
#else
36+
#define DOCOPT_API __declspec(dllimport)
37+
#endif
38+
#else
39+
#define DOCOPT_API
40+
#endif
2241
#endif
2342

2443
namespace docopt {
@@ -48,7 +67,7 @@ namespace docopt {
4867
/// @throws DocoptExitHelp if 'help' is true and the user has passed the '--help' argument
4968
/// @throws DocoptExitVersion if 'version' is true and the user has passed the '--version' argument
5069
/// @throws DocoptArgumentError if the user's argv did not match the usage patterns
51-
std::map<std::string, value> docopt_parse(std::string const& doc,
70+
std::map<std::string, value> DOCOPT_API docopt_parse(std::string const& doc,
5271
std::vector<std::string> const& argv,
5372
bool help = true,
5473
bool version = true,
@@ -61,7 +80,7 @@ namespace docopt {
6180
/// * DocoptExitHelp - print usage string and terminate (with exit code 0)
6281
/// * DocoptExitVersion - print version and terminate (with exit code 0)
6382
/// * DocoptArgumentError - print error and usage string and terminate (with exit code -1)
64-
std::map<std::string, value> docopt(std::string const& doc,
83+
std::map<std::string, value> DOCOPT_API docopt(std::string const& doc,
6584
std::vector<std::string> const& argv,
6685
bool help = true,
6786
std::string const& version = {},

0 commit comments

Comments
 (0)
0