8000 Merge pull request #61 from chrisdembia/windows-support-static-lib · docopt/docopt.cpp@af03fa0 · GitHub
[go: up one dir, main page]

Skip to content

Commit af03fa0

Browse files
authored
Merge pull request #61 from chrisdembia/windows-support-static-lib
Fix support for building static library with Visual Studio
2 parents 725519e + b6d3486 commit af03fa0

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

CMakeLists.txt

Lines changed: 15 additions & 5 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,8 +61,14 @@ 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

60-
# To control the exporting of symbols (on Windows).
61-
set_target_properties(docopt PROPERTIES DEFINE_SYMBOL DOCOPT_EXPORTS)
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()
6272

6373
if(NOT MSVC)
6474
set_target_properties(docopt PROPERTIES OUTPUT_NAME docopt)

docopt.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,26 @@
1717

1818
#ifdef DOCOPT_HEADER_ONLY
1919
#define DOCOPT_INLINE inline
20-
#define DOCOPTAPI
20+
#define DOCOPT_API
2121
#else
2222
#define DOCOPT_INLINE
2323

24-
// On Windows, export certain symbols so they are available
25-
// to users of docopt.dll (shared library).
26-
#ifdef WIN32
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.
2733
#ifdef DOCOPT_EXPORTS
28-
#define DOCOPTAPI __declspec(dllexport)
34+
#define DOCOPT_API __declspec(dllexport)
2935
#else
30-
#define DOCOPTAPI __declspec(dllimport)
36+
#define DOCOPT_API __declspec(dllimport)
3137
#endif
3238
#else
33-
#define DOCOPTAPI
39+
#define DOCOPT_API
3440
#endif
3541
#endif
3642

@@ -61,7 +67,7 @@ namespace docopt {
6167
/// @throws DocoptExitHelp if 'help' is true and the user has passed the '--help' argument
6268
/// @throws DocoptExitVersion if 'version' is true and the user has passed the '--version' argument
6369
/// @throws DocoptArgumentError if the user's argv did not match the usage patterns
64-
std::map<std::string, value> DOCOPTAPI docopt_parse(std::string const& doc,
70+
std::map<std::string, value> DOCOPT_API docopt_parse(std::string const& doc,
6571
std::vector<std::string> const& argv,
6672
bool help = true,
6773
bool version = true,
@@ -74,7 +80,7 @@ namespace docopt {
7480
/// * DocoptExitHelp - print usage string and terminate (with exit code 0)
7581
/// * DocoptExitVersion - print version and terminate (with exit code 0)
7682
/// * DocoptArgumentError - print error and usage string and terminate (with exit code -1)
77-
std::map<std::string, value> DOCOPTAPI docopt(std::string const& doc,
83+
std::map<std::string, value> DOCOPT_API docopt(std::string const& doc,
7884
std::vector<std::string> const& argv,
7985
bool help = true,
8086
std::string const& version = {},

0 commit comments

Comments
 (0)
0