aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-07-26 22:36:58 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-28 19:49:41 +0300
commitdeff9b91bed656fd54bd7fbb8a5c525eec5ab542 (patch)
treeee50b83f17888d2474d650a4fca73297d38a65b2
parent915260ad5e0d09eef98b76e294452a9216bc3e14 (diff)
Add DLL export/import support
-rw-r--r--bpkg/buildfile7
-rw-r--r--bpkg/export41
-rw-r--r--bpkg/manifest32
-rw-r--r--bpkg/manifest-parser6
-rw-r--r--bpkg/manifest-serializer6
5 files changed, 75 insertions, 17 deletions
diff --git a/bpkg/buildfile b/bpkg/buildfile
index b99d465..955e39d 100644
--- a/bpkg/buildfile
+++ b/bpkg/buildfile
@@ -12,8 +12,15 @@ lib{bpkg}: \
$libs
cxx.poptions =+ -I$src_root
+
lib{bpkg}: cxx.export.poptions = -I$src_root
+liba{bpkg}: cxx.export.poptions += -DLIBBPKG_STATIC
+libs{bpkg}: cxx.export.poptions += -DLIBBPKG_SHARED
+
+obja{*}: cxx.poptions += -DLIBBPKG_STATIC_BUILD
+objs{*}: cxx.poptions += -DLIBBPKG_SHARED_BUILD
+
# Install into the bpkg/ subdirectory of, say, /usr/include/.
#
install.include = $install.include/bpkg
diff --git a/bpkg/export b/bpkg/export
new file mode 100644
index 0000000..7bbb994
--- /dev/null
+++ b/bpkg/export
@@ -0,0 +1,41 @@
+// file : bpkg/export -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BPKG_EXPORT
+#define BPKG_EXPORT
+
+// Normally we don't export class templates (but do complete specializations),
+// inline functions, and classes with only inline member functions. Exporting
+// classes that inherit from non-exported/import bases (e.g., std::string)
+// will end up badly. The only known workarounds are to not inherit or to not
+// export. Also, MinGW GCC doesn't like seeing non-exported function being
+// used before their inline definition. The workaround is to reorder code. In
+// the end it's all trial and error.
+
+#if defined(LIBBPKG_STATIC) // Using static.
+# define LIBBPKG_EXPORT
+#elif defined(LIBBPKG_STATIC_BUILD) // Building static.
+# define LIBBPKG_EXPORT
+#elif defined(LIBBPKG_SHARED) // Using shared.
+# ifdef _WIN32
+# define LIBBPKG_EXPORT __declspec(dllimport)
+# else
+# define LIBBPKG_EXPORT
+# endif
+#elif defined(LIBBPKG_SHARED_BUILD) // Building shared.
+# ifdef _WIN32
+# define LIBBPKG_EXPORT __declspec(dllexport)
+# else
+# define LIBBPKG_EXPORT
+# endif
+#else
+// If none of the above macros are defined, then we assume we are being using
+// by some third-party build system that cannot/doesn't signal the library
+// type. Note that this fallback works for both static and shared but in case
+// of shared will be sub-optimal compared to having dllimport.
+//
+# define LIBBPKG_EXPORT // Using static or shared.
+#endif
+
+#endif // BPKG_EXPORT
diff --git a/bpkg/manifest b/bpkg/manifest
index 0c9362f..8e9c043 100644
--- a/bpkg/manifest
+++ b/bpkg/manifest
@@ -16,6 +16,8 @@
#include <butl/path>
#include <butl/optional>
+#include <bpkg/export>
+
namespace bpkg
{
class manifest_parser;
@@ -24,7 +26,7 @@ namespace bpkg
using strings = std::vector<std::string>;
- class version
+ class LIBBPKG_EXPORT version
{
public:
// Let's keep the members in the order they appear in the string
@@ -122,7 +124,7 @@ namespace bpkg
}
private:
- struct data_type
+ struct LIBBPKG_EXPORT data_type
{
enum class parse {full, upstream, release};
@@ -173,7 +175,7 @@ namespace bpkg
// change
// change-file
//
- class text_file
+ class LIBBPKG_EXPORT text_file
{
public:
using path_type = butl::path;
@@ -245,7 +247,7 @@ namespace bpkg
// depends
//
- struct dependency_constraint
+ struct LIBBPKG_EXPORT dependency_constraint
{
butl::optional<version> min_version;
butl::optional<version> max_version;
@@ -264,7 +266,7 @@ namespace bpkg
empty () const noexcept {return !min_version && !max_version;}
};
- std::ostream&
+ LIBBPKG_EXPORT std::ostream&
operator<< (std::ostream&, const dependency_constraint&);
inline bool
@@ -286,7 +288,7 @@ namespace bpkg
butl::optional<dependency_constraint> constraint;
};
- std::ostream&
+ LIBBPKG_EXPORT std::ostream&
operator<< (std::ostream&, const dependency&);
class dependency_alternatives: public std::vector<dependency>
@@ -300,7 +302,7 @@ namespace bpkg
: conditional (d), comment (std::move (c)) {}
};
- std::ostream&
+ LIBBPKG_EXPORT std::ostream&
operator<< (std::ostream&, const dependency_alternatives&);
// requires
@@ -316,7 +318,7 @@ namespace bpkg
: conditional (d), comment (std::move (c)) {}
};
- class package_manifest
+ class LIBBPKG_EXPORT package_manifest
{
public:
using version_type = bpkg::version;
@@ -345,6 +347,8 @@ namespace bpkg
butl::optional<std::string> sha256sum;
public:
+ package_manifest () = default; // VC export.
+
// Create individual package manifest.
//
package_manifest (manifest_parser&, bool ignore_unknown = false);
@@ -365,7 +369,7 @@ namespace bpkg
bool ignore_unknown);
};
- class package_manifests: public std::vector<package_manifest>
+ class LIBBPKG_EXPORT package_manifests: public std::vector<package_manifest>
{
public:
using base_type = std::vector<package_manifest>;
@@ -384,7 +388,7 @@ namespace bpkg
serialize (manifest_serializer&) const;
};
- class repository_location
+ class LIBBPKG_EXPORT repository_location
{
public:
// Create a special empty repository_location.
@@ -527,7 +531,7 @@ namespace bpkg
complement
};
- class repository_manifest
+ class LIBBPKG_EXPORT repository_manifest
{
public:
using email_type = bpkg::email;
@@ -566,6 +570,7 @@ namespace bpkg
effective_url (const repository_location&) const;
public:
+ repository_manifest () = default; // VC export.
repository_manifest (manifest_parser&, bool ignore_unknown = false);
repository_manifest (manifest_parser&,
manifest_name_value start,
@@ -575,7 +580,8 @@ namespace bpkg
serialize (manifest_serializer&) const;
};
- class repository_manifests: public std::vector<repository_manifest>
+ class LIBBPKG_EXPORT repository_manifests:
+ public std::vector<repository_manifest>
{
public:
using base_type = std::vector<repository_manifest>;
@@ -589,7 +595,7 @@ namespace bpkg
serialize (manifest_serializer&) const;
};
- class signature_manifest
+ class LIBBPKG_EXPORT signature_manifest
{
public:
// Checksum of the corresponding package_manifests.
diff --git a/bpkg/manifest-parser b/bpkg/manifest-parser
index 77918ee..8cbb768 100644
--- a/bpkg/manifest-parser
+++ b/bpkg/manifest-parser
@@ -12,9 +12,11 @@
#include <butl/char-scanner>
+#include <bpkg/export>
+
namespace bpkg
{
- class manifest_parsing: public std::runtime_error
+ class LIBBPKG_EXPORT manifest_parsing: public std::runtime_error
{
public:
manifest_parsing (const std::string& name,
@@ -44,7 +46,7 @@ namespace bpkg
empty () const {return name.empty () && value.empty ();}
};
- class manifest_parser: protected butl::char_scanner
+ class LIBBPKG_EXPORT manifest_parser: protected butl::char_scanner
{
public:
manifest_parser (std::istream& is, const std::string& name)
diff --git a/bpkg/manifest-serializer b/bpkg/manifest-serializer
index 3116279..501fd30 100644
--- a/bpkg/manifest-serializer
+++ b/bpkg/manifest-serializer
@@ -10,9 +10,11 @@
#include <cstddef> // size_t
#include <stdexcept> // runtime_error
+#include <bpkg/export>
+
namespace bpkg
{
- class manifest_serialization: public std::runtime_error
+ class LIBBPKG_EXPORT manifest_serialization: public std::runtime_error
{
public:
manifest_serialization (const std::string& name,
@@ -22,7 +24,7 @@ namespace bpkg
std::string description;
};
- class manifest_serializer
+ class LIBBPKG_EXPORT manifest_serializer
{
public:
manifest_serializer (std::ostream& os, const std::string& name)