The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
build_info.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2015 - 2016 by Ignacio Riquelme Morelle <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
17 #include "build_info.hpp"
18 
19 #include "formatter.hpp"
20 #include "gettext.hpp"
21 
22 #include <algorithm>
23 
24 #include <SDL.h>
25 #include <SDL_image.h>
26 #include <SDL_mixer.h>
27 #include <SDL_ttf.h>
28 #include <SDL_net.h>
29 
30 #include <boost/version.hpp>
31 
32 #include <pango/pangocairo.h>
33 
34 #ifdef HAVE_LIBPNG
35 #include <png.h>
36 #endif
37 
38 namespace game_config
39 {
40 
41 namespace {
42 
43 struct version_table_manager
44 {
45  std::vector<std::string> compiled, linked, names;
46  std::vector<optional_feature> features;
47 
48  version_table_manager();
49 };
50 
51 const version_table_manager versions;
52 
53 #if 0
54 std::string format_version(unsigned a, unsigned b, unsigned c)
55 {
56  return (formatter() << a << '.' << b << '.' << c).str();
57 }
58 #endif
59 
60 std::string format_version(const SDL_version& v)
61 {
62  return (formatter() << unsigned(v.major) << '.'
63  << unsigned(v.minor) << '.'
64  << unsigned(v.patch)).str();
65 }
66 
67 version_table_manager::version_table_manager()
68  : compiled(LIB_COUNT, "")
69  , linked(LIB_COUNT, "")
70  , names(LIB_COUNT, "")
71  , features()
72 {
73  SDL_version sdl_version;
74  const SDL_version* sdl_rt_version = nullptr;
75 
76 
77  //
78  // SDL
79  //
80 
81  SDL_VERSION(&sdl_version);
82  compiled[LIB_SDL] = format_version(sdl_version);
83 
84  SDL_GetVersion(&sdl_version);
85  linked[LIB_SDL] = format_version(sdl_version);
86 
87  names[LIB_SDL] = "SDL";
88 
89  //
90  // SDL_image
91  //
92 
93  SDL_IMAGE_VERSION(&sdl_version);
94  compiled[LIB_SDL_IMAGE] = format_version(sdl_version);
95 
96  sdl_rt_version = IMG_Linked_Version();
97  if(sdl_rt_version) {
98  linked[LIB_SDL_IMAGE] = format_version(*sdl_rt_version);
99  }
100 
101  names[LIB_SDL_IMAGE] = "SDL_image";
102 
103  //
104  // SDL_mixer
105  //
106 
107  SDL_MIXER_VERSION(&sdl_version);
108  compiled[LIB_SDL_MIXER] = format_version(sdl_version);
109 
110  sdl_rt_version = Mix_Linked_Version();
111  if(sdl_rt_version) {
112  linked[LIB_SDL_MIXER] = format_version(*sdl_rt_version);
113  }
114 
115  names[LIB_SDL_MIXER] = "SDL_mixer";
116 
117  //
118  // SDL_ttf
119  //
120 
121  SDL_TTF_VERSION(&sdl_version);
122  compiled[LIB_SDL_TTF] = format_version(sdl_version);
123 
124  sdl_rt_version = TTF_Linked_Version();
125  if(sdl_rt_version) {
126  linked[LIB_SDL_TTF] = format_version(*sdl_rt_version);
127  }
128 
129  names[LIB_SDL_TTF] = "SDL_ttf";
130 
131  //
132  // Boost
133  //
134 
135  compiled[LIB_BOOST] = BOOST_LIB_VERSION;
136  std::replace(compiled[LIB_BOOST].begin(), compiled[LIB_BOOST].end(), '_', '.');
137  names[LIB_BOOST] = "Boost";
138 
139  //
140  // Cairo
141  //
142 
143  compiled[LIB_CAIRO] = CAIRO_VERSION_STRING;
144  linked[LIB_CAIRO] = cairo_version_string();
145  names[LIB_CAIRO] = "Cairo";
146 
147  //
148  // Pango
149  //
150 
151  compiled[LIB_PANGO] = PANGO_VERSION_STRING;
152  linked[LIB_PANGO] = pango_version_string();
153  names[LIB_PANGO] = "Pango";
154 
155  //
156  // libpng
157  //
158 
159 #ifdef HAVE_LIBPNG
160  compiled[LIB_PNG] = PNG_LIBPNG_VER_STRING;
161  linked[LIB_PNG] = png_get_libpng_ver(nullptr);
162  names[LIB_PNG] = "libpng";
163 #endif
164 
165  //
166  // Features table.
167  //
168 
169  features.push_back(N_("feature^Experimental OpenMP support"));
170 #ifdef _OPENMP
171  features.back().enabled = true;
172 #endif
173 
174  features.push_back(N_("feature^PNG screenshots"));
175 #ifdef HAVE_LIBPNG
176  features.back().enabled = true;
177 #endif
178 
179  features.push_back(N_("feature^Lua console completion"));
180 #ifdef HAVE_HISTORY
181  features.back().enabled = true;
182 #endif
183 
184  features.push_back(N_("feature^Legacy bidirectional rendering"));
185 #ifdef HAVE_FRIBIDI
186  features.back().enabled = true;
187 #endif
188 
189 #ifdef _X11
190 
191  features.push_back(N_("feature^D-Bus notifications back end"));
192 #ifdef HAVE_LIBDBUS
193  features.back().enabled = true;
194 #endif
195 
196 #endif /* _X11 */
197 
198 #ifdef _WIN32
199  // Always compiled in.
200  features.push_back(N_("feature^Win32 notifications back end"));
201  features.back().enabled = true;
202 #endif
203 
204 #ifdef __APPLE__
205 
206  features.push_back(N_("feature^Cocoa notifications back end"));
207 #ifdef HAVE_NS_USER_NOTIFICATION
208  features.back().enabled = true;
209 #endif
210 
211  features.push_back(N_("feature^Growl notifications back end"));
212 #ifdef HAVE_GROWL
213  features.back().enabled = true;
214 #endif
215 
216 #endif /* __APPLE__ */
217 }
218 
219 const std::string empty_version = "";
220 
221 } // end anonymous namespace 1
222 
223 std::vector<optional_feature> optional_features_table()
224 {
225  std::vector<optional_feature> res = versions.features;
226 
227  for(size_t k = 0; k < res.size(); ++k) {
228  res[k].name = _(res[k].name.c_str());
229  }
230  return res;
231 }
232 
234 {
235  if(lib >= LIB_COUNT) {
236  return empty_version;
237  }
238 
239  return versions.compiled[lib];
240 }
241 
243 {
244  if(lib >= LIB_COUNT) {
245  return empty_version;
246  }
247 
248  return versions.linked[lib];
249 }
250 
252 {
253  if(lib >= LIB_COUNT) {
254  return empty_version;
255  }
256 
257  return versions.names[lib];
258 }
259 
260 namespace {
261 
262 bool strlen_comparator(const std::string& a, const std::string& b)
263 {
264  return a.length() < b.length();
265 }
266 
267 size_t max_strlen(const std::vector<std::string>& strs)
268 {
269  const std::vector<std::string>::const_iterator it =
270  std::max_element(strs.begin(), strs.end(), strlen_comparator);
271 
272  return it != strs.end() ? it->length() : 0;
273 }
274 
275 } // end anonymous namespace 2
276 
278 {
279  std::ostringstream o;
280 
281  const size_t col2_start = max_strlen(versions.names) + 2;
282  const size_t col3_start = max_strlen(versions.compiled) + 1;
283 
284  for(unsigned n = 0; n < LIB_COUNT; ++n)
285  {
286  const std::string& name = versions.names[n];
287  const std::string& compiled = versions.compiled[n];
288  const std::string& linked = versions.linked[n];
289 
290  if(name.empty()) {
291  continue;
292  }
293 
294  o << name << ": ";
295 
296  const size_t pos2 = name.length() + 2;
297  if(pos2 < col2_start) {
298  o << std::string(col2_start - pos2, ' ');
299  }
300 
301  o << compiled;
302 
303  if(!linked.empty()) {
304  const size_t pos3 = compiled.length() + 1;
305  if(pos3 < col3_start) {
306  o << std::string(col3_start - pos3, ' ');
307  }
308  o << " (runtime " << linked << ")";
309  }
310 
311  o << '\n';
312  }
313 
314  return o.str();
315 }
316 
318 {
319  // Yes, it's for stdout/stderr but we still want the localized version so
320  // that the context prefixes are stripped.
321  const std::vector<optional_feature>& features = optional_features_table();
322 
323  size_t col2_start = 0;
324 
325  for(size_t k = 0; k < features.size(); ++k)
326  {
327  col2_start = std::max(col2_start, features[k].name.length() + 2);
328  }
329 
330  std::ostringstream o;
331 
332  for(size_t k = 0; k < features.size(); ++k)
333  {
334  const optional_feature& f = features[k];
335 
336  o << f.name << ": ";
337 
338  const size_t pos2 = f.name.length() + 2;
339  if(pos2 < col2_start) {
340  o << std::string(col2_start - pos2, ' ');
341  }
342 
343  o << (f.enabled ? "yes" : "no") << '\n';
344  }
345 
346  return o.str();
347 }
348 
349 } // end namespace game_config
std::string library_versions_report()
Produce a plain-text report of library versions suitable for stdout/stderr.
Definition: build_info.cpp:277
const GLfloat * c
Definition: glew.h:12741
std::string optional_features_report()
Produce a plain-text report of features suitable for stdout/stderr.
Definition: build_info.cpp:317
const std::string & library_build_version(LIBRARY_ID lib)
Retrieve the build-time version number of the given library.
Definition: build_info.cpp:233
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
GLuint GLuint end
Definition: glew.h:1221
const std::string & library_name(LIBRARY_ID lib)
Retrieve the user-visible name for the given library.
Definition: build_info.cpp:251
std::vector< optional_feature > optional_features_table()
Return a localized features table.
Definition: build_info.cpp:223
std::vector< optional_feature > features
Definition: build_info.cpp:46
std::ostringstream wrapper.
Definition: formatter.hpp:32
const GLdouble * v
Definition: glew.h:1359
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
GLuint const GLuint * names
Definition: glew.h:2552
GLuint res
Definition: glew.h:9258
std::vector< std::string > linked
Definition: build_info.cpp:45
Game configuration data as global variables.
Definition: build_info.cpp:38
std::vector< std::string > names
Definition: build_info.cpp:45
const std::string & library_runtime_version(LIBRARY_ID lib)
Retrieve the runtime version number of the given library.
Definition: build_info.cpp:242
#define N_(String)
Definition: gettext.hpp:90
std::string replace(std::string str, const std::string &src, const std::string &dst)
Replace all instances of src in str with dst.
GLuint const GLchar * name
Definition: glew.h:1782
GLclampd n
Definition: glew.h:5903
std::vector< std::string > compiled
Definition: build_info.cpp:45
GLsizei const GLcharARB ** string
Definition: glew.h:4503
GLclampf f
Definition: glew.h:3024