blob: 7959da1702c287eae71457fc3c62ffe7c969f1a4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// file : libbuild2/cc/pkgconfig.hxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#ifndef LIBBUILD2_CC_PKGCONFIG_HXX
#define LIBBUILD2_CC_PKGCONFIG_HXX
// In order not to complicate the bootstrap procedure with libpkg-config
// building, exclude functionality that involves reading of .pc files.
//
#ifndef BUILD2_BOOTSTRAP
#ifndef BUILD2_LIBPKGCONF
# include <libpkg-config/pkg-config.h>
#else
# include <libpkgconf/libpkgconf.h>
#endif
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
namespace build2
{
namespace cc
{
// Load package information from a .pc file. Filter out the -I/-L options
// that refer to system directories. This makes sure all the system search
// directories are "pushed" to the back which minimizes the chances of
// picking up wrong (e.g., old installed version) header/library.
//
// Note that the prerequisite package .pc files search order is as
// follows:
//
// - in the directory of the specified file
// - in pc_dirs directories (in the specified order)
//
// Issue diagnostics and throw failed on any errors.
//
class pkgconfig
{
public:
using path_type = build2::path;
path_type path;
public:
pkgconfig (path_type,
const dir_paths& pc_dirs,
const dir_paths& sys_hdr_dirs,
const dir_paths& sys_lib_dirs);
// Create an unloaded/empty object. Querying package information on such
// an object is illegal.
//
pkgconfig () = default;
~pkgconfig ();
// Movable-only type.
//
pkgconfig (pkgconfig&&);
pkgconfig& operator= (pkgconfig&&);
pkgconfig (const pkgconfig&) = delete;
pkgconfig& operator= (const pkgconfig&) = delete;
strings
cflags (bool static_) const;
strings
libs (bool static_) const;
optional<string>
variable (const char*) const;
optional<string>
variable (const string& s) const {return variable (s.c_str ());}
private:
void
free ();
#ifndef BUILD2_LIBPKGCONF
pkg_config_client_t* client_ = nullptr;
pkg_config_pkg_t* pkg_ = nullptr;
#else
pkgconf_client_t* client_ = nullptr;
pkgconf_pkg_t* pkg_ = nullptr;
#endif
};
inline pkgconfig::
~pkgconfig ()
{
if (client_ != nullptr) // Not empty.
free ();
}
inline pkgconfig::
pkgconfig (pkgconfig&& p)
: path (move (p.path)),
client_ (p.client_),
pkg_ (p.pkg_)
{
p.client_ = nullptr;
p.pkg_ = nullptr;
}
inline pkgconfig& pkgconfig::
operator= (pkgconfig&& p)
{
if (this != &p)
{
if (client_ != nullptr) // Not empty.
free ();
path = move (p.path);
client_ = p.client_;
pkg_ = p.pkg_;
p.client_ = nullptr;
p.pkg_ = nullptr;
}
return *this;
}
}
}
#endif // BUILD2_BOOTSTRAP
#endif // LIBBUILD2_CC_PKGCONFIG_HXX
|