jbsrc/lib/src/core/jb-feature.c (9504B) - raw
1 /* 2 * JB, the Jean-Yves Lefort's Build System 3 * Copyright (C) 2008 Jean-Yves Lefort <jylefort@brutele.be> 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 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #include <stdio.h> 21 #include <string.h> 22 #include "jb-util.h" 23 #include "jb-variable.h" 24 #include "jb-tests.h" 25 #include "jb-feature.h" 26 27 typedef struct 28 { 29 int major; 30 int minor; 31 int micro; 32 } Version; 33 34 static const JBFeature **_features = NULL; 35 static int _num_features = 0; 36 37 gboolean jb_intltool_use_xml = TRUE; 38 39 void 40 jb_feature_set_list (const JBFeature **features, int num_features) 41 { 42 g_return_if_fail(features != NULL); 43 44 _features = features; 45 _num_features = num_features; 46 } 47 48 gboolean 49 jb_feature_is_enabled (JBFeature *feature) 50 { 51 int i; 52 53 g_return_val_if_fail(feature != NULL, FALSE); 54 55 for (i = 0; i < _num_features; i++) 56 if (_features[i] == feature) 57 return TRUE; 58 59 return FALSE; 60 } 61 62 void 63 jb_feature_init (void) 64 { 65 int i; 66 67 for (i = 0; i < _num_features; i++) 68 { 69 const JBFeature *feature = _features[i]; 70 71 if (feature->init) 72 feature->init(); 73 } 74 } 75 76 void 77 jb_feature_configure (void) 78 { 79 int i; 80 81 for (i = 0; i < _num_features; i++) 82 { 83 const JBFeature *feature = _features[i]; 84 85 if (feature->configure) 86 feature->configure(); 87 } 88 } 89 90 static void 91 pkg_config_init (void) 92 { 93 /* NO_REPORT since it is only used in configure */ 94 jb_register_program("pkg-config", JB_VARIABLE_NO_REPORT); 95 } 96 97 static void 98 gettext_init (void) 99 { 100 jb_register_program("msgfmt", 0); 101 } 102 103 static void 104 gettext_configure (void) 105 { 106 static const char *functions = "ngettext dgettext bind_textdomain_codeset"; 107 108 if (jb_check_functions(functions, NULL)) 109 jb_variable_set_package_flags("gettext", NULL, "-DENABLE_NLS", NULL, NULL); 110 else if (jb_check_functions(functions, "intl")) 111 jb_variable_set_package_flags("gettext", NULL, "-DENABLE_NLS", NULL, "-lintl"); 112 else 113 jb_error("gettext found neither in libc nor in libintl"); 114 115 jb_require_program("msgfmt"); 116 } 117 118 static void 119 intltool_init (void) 120 { 121 jb_register_program("perl", 0); 122 } 123 124 static void 125 intltool_configure (void) 126 { 127 jb_require_program("perl"); 128 129 if (jb_intltool_use_xml) 130 { 131 gboolean result; 132 133 jb_message_checking("for XML::Parser"); 134 result = jb_exec_expand(NULL, NULL, "$perl -e 'require XML::Parser'", NULL); 135 jb_message_result_bool(result); 136 137 if (! result) 138 jb_error("intltool requires the XML::Parser Perl module"); 139 } 140 } 141 142 static void 143 gconf_init (void) 144 { 145 jb_register_program("gconftool-2", 0); 146 147 jb_variable_add_string("gconf-config-source", 148 "GConf configuration source address", 149 jb_variable_group_installation_options, 150 0, 151 "autodetect"); 152 jb_variable_add_string("gconf-schemas-dir", 153 "GConf schemas installation directory", 154 jb_variable_group_installation_options, 155 0, 156 "$sysconfdir/gconf/schemas"); 157 jb_variable_add_bool("install-gconf-schemas", 158 "install GConf schemas", 159 jb_variable_group_installation_options, 160 0, 161 TRUE); 162 } 163 164 static void 165 gconf_configure (void) 166 { 167 JBVariable *variable; 168 169 jb_require_program("gconftool-2"); 170 171 if (! strcmp(jb_variable_get_string("gconf-config-source"), "autodetect")) 172 { 173 char *config_source; 174 175 if (! jb_exec_expand(&config_source, NULL, "$gconftool-2 --get-default-source", NULL)) 176 jb_error("unable to detect the GConf configuration source address"); 177 178 jb_variable_set_string("gconf-config-source", config_source); 179 g_free(config_source); 180 } 181 182 /* fix the default schemas dir on Ubuntu */ 183 variable = jb_variable_get_variable_or_error("gconf-schemas-dir"); 184 if (! variable->user_set) 185 { 186 static const char *ubuntu_dir = "$datadir/gconf/schemas"; 187 char *expanded; 188 189 expanded = jb_variable_expand(ubuntu_dir, NULL); 190 191 if (g_file_test(expanded, G_FILE_TEST_IS_DIR)) 192 jb_variable_set_string("gconf-schemas-dir", ubuntu_dir); 193 194 g_free(expanded); 195 } 196 } 197 198 static void 199 gnome_help_init (void) 200 { 201 /* NO_REPORT since it is only used in configure */ 202 jb_register_program("scrollkeeper-config", JB_VARIABLE_NO_REPORT); 203 jb_register_program("scrollkeeper-preinstall", 0); 204 jb_register_program("scrollkeeper-update", 0); 205 206 jb_variable_add_string("help-dir", 207 "GNOME help directory", 208 jb_variable_group_installation_options, 209 0, 210 "$datadir/gnome/help"); 211 jb_variable_add_string("omf-dir", 212 "OMF directory", 213 jb_variable_group_installation_options, 214 0, 215 "autodetect"); 216 jb_variable_add_string("scrollkeeper-dir", 217 "ScrollKeeper database directory", 218 jb_variable_group_installation_options, 219 0, 220 "autodetect"); 221 } 222 223 static void 224 gnome_help_check_dir (const char *name, 225 const char *description, 226 const char *scrollkeeper_config_arg) 227 { 228 const char *dir; 229 char *result; 230 231 dir = jb_variable_get_string(name); 232 if (strcmp(dir, "autodetect")) 233 return; 234 235 jb_require_program("scrollkeeper-config"); 236 237 jb_message_checking("for the %s", description); 238 239 if (jb_exec_expand(&result, NULL, "$scrollkeeper-config $arg", 240 "arg", scrollkeeper_config_arg, 241 NULL)) 242 { 243 jb_message_result_string(result); 244 jb_variable_set_string(name, result); 245 } 246 else 247 { 248 jb_message_result_string("not found"); 249 jb_error("unable to autodetect the %s", description); 250 } 251 252 g_free(result); 253 } 254 255 static void 256 gnome_help_configure (void) 257 { 258 jb_require_program("scrollkeeper-preinstall"); 259 jb_require_program("scrollkeeper-update"); 260 261 gnome_help_check_dir("omf-dir", 262 "OMF directory", 263 "--omfdir"); 264 gnome_help_check_dir("scrollkeeper-dir", 265 "ScrollKeeper database directory", 266 "--pkglocalstatedir"); 267 } 268 269 static gboolean 270 parse_version (const char *version_string, Version *version) 271 { 272 int _major; 273 int _minor; 274 int _micro; 275 276 switch (sscanf(version_string, "%d.%d.%d", &_major, &_minor, &_micro)) 277 { 278 case 1: 279 version->major = _major; 280 version->minor = 0; 281 version->micro = 0; 282 return TRUE; 283 284 case 2: 285 version->major = _major; 286 version->minor = _minor; 287 version->micro = 0; 288 return TRUE; 289 290 case 3: 291 version->major = _major; 292 version->minor = _minor; 293 version->micro = _micro; 294 return TRUE; 295 296 default: 297 return FALSE; 298 } 299 } 300 301 static int 302 version_to_int (Version *version) 303 { 304 return (version->major << 16) + (version->minor << 8) + version->micro; 305 } 306 307 static void 308 gob2_init (void) 309 { 310 jb_register_program("gob2", 0); 311 jb_variable_set_string("gob2-minversion", "2.0"); 312 } 313 314 static gboolean 315 parse_gob2_version_output (char *str, 316 char **version_string, 317 Version *version) 318 { 319 char *space; 320 char *_version_string; 321 322 space = strrchr(str, ' '); 323 if (space == NULL) 324 return FALSE; 325 326 _version_string = space + 1; 327 if (parse_version(_version_string, version)) 328 { 329 *version_string = _version_string; 330 return TRUE; 331 } 332 333 return FALSE; 334 } 335 336 static char * 337 get_gob2_not_found_error (const char *minversion) 338 { 339 return g_strdup_printf("One or more .gob source files were modified but gob2 was not found. Please install gob2 >= %s and run configure again.", 340 minversion); 341 } 342 343 static void 344 gob2_configure (void) 345 { 346 const char *minversion_string; 347 Version minversion; 348 char *error = NULL; 349 350 minversion_string = jb_variable_get_string("gob2-minversion"); 351 if (! parse_version(minversion_string, &minversion)) 352 g_error("invalid gob2-minversion \"%s\"", minversion_string); 353 354 if (jb_check_program("gob2")) 355 { 356 char *output; 357 gboolean result = FALSE; 358 359 jb_message_checking("for gob2 >= %s", minversion_string); 360 361 if (jb_exec_expand(NULL, &output, "$gob2 --version", NULL)) 362 { 363 char *version_string; 364 Version version; 365 366 if (parse_gob2_version_output(output, &version_string, &version)) 367 { 368 if (version_to_int(&version) >= version_to_int(&minversion)) 369 result = TRUE; 370 else 371 error = g_strdup_printf("One or more .gob source files were modified but the version of gob2 (%s) is too old. Please install gob2 >= %s and run configure again.", 372 version_string, 373 minversion_string); 374 } 375 else 376 error = get_gob2_not_found_error(minversion_string); 377 } 378 else 379 error = get_gob2_not_found_error(minversion_string); 380 381 g_free(output); 382 383 jb_message_result_bool(result); 384 } 385 else 386 error = get_gob2_not_found_error(minversion_string); 387 388 jb_variable_set_string("gob2-error", error); 389 g_free(error); 390 } 391 392 JBFeature jb_pkg_config_feature = { 393 pkg_config_init, 394 NULL 395 }; 396 397 JBFeature jb_gettext_feature = { 398 gettext_init, 399 gettext_configure 400 }; 401 402 JBFeature jb_intltool_feature = { 403 intltool_init, 404 intltool_configure 405 }; 406 407 JBFeature jb_gconf_feature = { 408 gconf_init, 409 gconf_configure 410 }; 411 412 JBFeature jb_gnome_help_feature = { 413 gnome_help_init, 414 gnome_help_configure 415 }; 416 417 JBFeature jb_gob2_feature = { 418 gob2_init, 419 gob2_configure 420 };