From deff9b91bed656fd54bd7fbb8a5c525eec5ab542 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 26 Jul 2016 22:36:58 +0300 Subject: Add DLL export/import support --- bpkg/buildfile | 7 +++++++ bpkg/export | 41 +++++++++++++++++++++++++++++++++++++++++ bpkg/manifest | 32 +++++++++++++++++++------------- bpkg/manifest-parser | 6 ++++-- bpkg/manifest-serializer | 6 ++++-- 5 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 bpkg/export 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 #include +#include + namespace bpkg { class manifest_parser; @@ -24,7 +26,7 @@ namespace bpkg using strings = std::vector; - 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 min_version; butl::optional 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 constraint; }; - std::ostream& + LIBBPKG_EXPORT std::ostream& operator<< (std::ostream&, const dependency&); class dependency_alternatives: public std::vector @@ -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 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 + class LIBBPKG_EXPORT package_manifests: public std::vector { public: using base_type = std::vector; @@ -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 + class LIBBPKG_EXPORT repository_manifests: + public std::vector { public: using base_type = std::vector; @@ -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 +#include + 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 // size_t #include // runtime_error +#include + 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) -- cgit v1.1