1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker and Richard O'Keefe 4 E-mail: J.Wielemaker@cs.vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2014-2026, VU University Amsterdam 7 CWI, Amsterdam 8 SWI-Prolog Solutions b.v. 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35*/ 36 37:- module(check_installation, 38 [ check_installation/0, 39 check_installation/1, % -Issues 40 check_config_files/0, 41 update_config_files/0, 42 test_installation/0, 43 test_installation/1 % +Options 44 ]). 45:- autoload(library(apply), [maplist/2, maplist/3]). 46:- autoload(library(archive), [archive_open/3, archive_close/1]). 47:- autoload(library(lists), [append/3, member/2]). 48:- autoload(library(occurs), [sub_term/2]). 49:- autoload(library(option), [option/2, merge_options/3]). 50:- autoload(library(prolog_source), [path_segments_atom/2]). 51:- use_module(library(settings), [setting/2]). 52:- autoload(library(dcg/high_order), [sequence//2, sequence/4]). 53:- autoload(library(error), [must_be/2]). 54:- autoload(library(pce), [get/3, get/4]).
http://www.swi-prolog.org/build/issues/. If not provided,
the library file with extension .html is used.windows, unix or linux. If present, the component
is only checked for if we are running on a version of the
specified operating system.87% Feature tests 88component(tcmalloc, 89 #{ optional:true, 90 test:test_tcmalloc, 91 url:'tcmalloc.html', 92 os:linux 93 }). 94component(gmp, 95 #{ test:current_prolog_flag(bounded, false), 96 url:'gmp.html' 97 }). 98% Packages that depend on foreign libraries 99component(library(archive), #{features:archive_features}). 100component(library(cgi), #{}). 101component(library(crypt), #{}). 102component(library(bdb), #{}). 103component(library(double_metaphone), #{}). 104component(library(editline), #{}). 105component(library(filesex), #{}). 106component(library(http/http_stream), #{}). 107component(library(json), #{}). 108component(library(http/jquery), #{features:jquery_file}). 109component(library(isub), #{}). 110component(library(janus), #{features:python_version}). 111component(library(jpl), #{}). 112component(library(memfile), #{}). 113component(library(odbc), #{}). 114component(library(pce), 115 #{pre:use_foreign_library(pce_principal:foreign(pl2xpce)), 116 url:'xpce.html', 117 features:pce_features}). 118component(library(pcre), #{features:pcre_features}). 119component(library(pdt_console), #{}). 120component(library(porter_stem), #{}). 121component(library(process), #{}). 122component(library(protobufs), #{}). 123component(library(readutil), #{}). 124component(library(rlimit), #{os:unix}). 125component(library(semweb/rdf_db), #{}). 126component(library(semweb/rdf_ntriples), #{}). 127component(library(semweb/turtle), #{}). 128component(library(sgml), #{}). 129component(library(sha), #{}). 130component(library(snowball), #{}). 131component(library(socket), #{}). 132component(library(ssl), #{features:ssl_version}). 133component(library(sweep_link), #{features:sweep_emacs_module}). 134component(library(crypto), #{}). 135component(library(syslog), #{os:unix}). 136component(library(table), #{}). 137component(library(time), #{}). 138component(library(tipc/tipc), #{os:linux}). 139component(library(unicode), #{}). 140component(library(uri), #{}). 141component(library(uuid), #{}). 142component(library(yaml), #{}). 143component(library(zlib), #{}). 144 145issue_base('http://www.swi-prolog.org/build/issues/'). 146 147:- thread_local 148 issue/1. 149 150:- meta_predicate 151 run_silent(, ).
If issues are found it prints a diagnostic message with a link to a wiki page with additional information about the issue.
168check_installation :-
169 print_message(informational, installation(checking)),
170 check_installation_(InstallIssues),
171 check_on_path,
172 check_config_files(ConfigIssues),
173 check_autoload,
174 maplist(print_message(warning), ConfigIssues),
175 append(InstallIssues, ConfigIssues, Issues),
176 ( Issues == []
177 -> print_message(informational, installation(perfect))
178 ; length(Issues, Count),
179 print_message(warning, installation(imperfect(Count)))
180 ).optional_not_found
(optional component is not present), not_found (component is
not present) or failed (component is present but cannot be
loaded).190check_installation(Issues) :- 191 check_installation_(Issues0), 192 maplist(public_issue, Issues0, Issues). 193 194public_issue(installation(Term), Source-Issue) :- 195 functor(Term, Issue, _), 196 arg(1, Term, Properties), 197 Source = Properties.source. 198 199check_installation_(Issues) :- 200 retractall(issue(_)), 201 forall(component(Source, _Properties), 202 check_component(Source)), 203 findall(I, retract(issue(I)), Issues). 204 205check_component(Source) :- 206 component(Source, Properties), 207 !, 208 check_component(Source, Properties.put(source,Source)). 209 210check_component(_Source, Properties) :- 211 OS = Properties.get(os), 212 \+ current_os(OS), 213 !. 214check_component(Source, Properties) :- 215 compound(Source), 216 !, 217 check_source(Source, Properties). 218check_component(Feature, Properties) :- 219 print_message(informational, installation(checking(Feature))), 220 ( call(Properties.test) 221 -> print_message(informational, installation(ok)) 222 ; print_issue(installation(missing(Properties))) 223 ). 224 225check_source(Source, Properties) :- 226 exists_source(Source), 227 !, 228 print_message(informational, installation(loading(Source))), 229 ( run_silent(( ( Pre = Properties.get(pre) 230 -> call(Pre) 231 ; true 232 ), 233 load_files(Source, [silent(true), if(true)]) 234 ), 235 Properties.put(action, load)) 236 -> test_component(Properties), 237 print_message(informational, installation(ok)), 238 check_features(Properties) 239 ; true 240 ). 241check_source(_Source, Properties) :- 242 Properties.get(optional) == true, 243 !, 244 print_message(silent, 245 installation(optional_not_found(Properties))). 246check_source(_Source, Properties) :- 247 print_issue(installation(not_found(Properties))). 248 249current_os(unix) :- current_prolog_flag(unix, true). 250current_os(windows) :- current_prolog_flag(windows, true). 251current_os(linux) :- current_prolog_flag(arch, Arch), 252 sub_atom(Arch, _, _, _, linux).
258test_component(Dict) :- 259 Test = Dict.get(test), 260 !, 261 call(Test). 262test_component(_).
271check_features(Dict) :- 272 Test = Dict.get(features), 273 !, 274 catch(Test, Error, 275 ( print_message(warning, Error), 276 fail)). 277check_features(_).
285run_silent(Goal, Properties) :-
286 run_collect_messages(Goal, Result, Messages),
287 ( Result == true,
288 Messages == []
289 -> true
290 ; print_issue(installation(failed(Properties, Result, Messages))),
291 fail
292 ).true, false or exception(Error)
and messages with a list of generated error and warning
messages. Each message is a term:
message(Term,Kind,Lines)
304:- thread_local 305 got_message/1. 306 307run_collect_messages(Goal, Result, Messages) :- 308 setup_call_cleanup( 309 asserta((user:thread_message_hook(Term,Kind,Lines) :- 310 error_kind(Kind), 311 assertz(got_message(message(Term,Kind,Lines)))), Ref), 312 ( catch(Goal, E, true) 313 -> ( var(E) 314 -> Result0 = true 315 ; Result0 = exception(E) 316 ) 317 ; Result0 = false 318 ), 319 erase(Ref)), 320 findall(Msg, retract(got_message(Msg)), Messages), 321 Result = Result0. 322 323error_kind(warning). 324error_kind(error). 325 326 327 /******************************* 328 * SPECIAL TESTS * 329 *******************************/
333:- if(current_predicate(malloc_property/1)). 334test_tcmalloc :- 335 malloc_property('generic.current_allocated_bytes'(Bytes)), 336 Bytes > 1 000 000. 337:- else. 338test_tcmalloc :- 339 fail. 340:- endif.
346archive_features :- 347 tmp_file_stream(utf8, Name, Out), 348 close(Out), 349 findall(F, archive_filter(F, Name), Filters), 350 print_message(informational, installation(archive(filters, Filters))), 351 findall(F, archive_format(F, Name), Formats), 352 print_message(informational, installation(archive(formats, Formats))), 353 delete_file(Name). 354 355archive_filter(F, Name) :- 356 a_filter(F), 357 catch(archive_open(Name, A, [filter(F)]), E, true), 358 ( var(E) 359 -> archive_close(A) 360 ; true 361 ), 362 \+ subsumes_term(error(domain_error(filter, _),_), E). 363 364archive_format(F, Name) :- 365 a_format(F), 366 catch(archive_open(Name, A, [format(F)]), E, true), 367 ( var(E) 368 -> archive_close(A) 369 ; true 370 ), 371 \+ subsumes_term(error(domain_error(format, _),_), E). 372 373a_filter(bzip2). 374a_filter(compress). 375a_filter(gzip). 376a_filter(grzip). 377a_filter(lrzip). 378a_filter(lzip). 379a_filter(lzma). 380a_filter(lzop). 381a_filter(none). 382a_filter(rpm). 383a_filter(uu). 384a_filter(xz). 385 386a_format('7zip'). 387a_format(ar). 388a_format(cab). 389a_format(cpio). 390a_format(empty). 391a_format(gnutar). 392a_format(iso9660). 393a_format(lha). 394a_format(mtree). 395a_format(rar). 396a_format(raw). 397a_format(tar). 398a_format(xar). 399a_format(zip).
403pcre_features :- 404 findall(X, pcre_missing(X), Missing), 405 ( Missing == [] 406 -> true 407 ; print_message(warning, installation(pcre_missing(Missing))) 408 ), 409 ( re_config(compiled_widths(Widths)), 410 1 =:= Widths /\ 1 411 -> true 412 ; print_message(warning, installation(pcre_missing('8-bit support'))) 413 ). 414 415pcre_missing(X) :- 416 pcre_must_have(X), 417 Term =.. [X,true], 418 \+ catch(re_config(Term), _, fail). 419 420pcre_must_have(unicode).
428pce_features :- 429 forall(pce_formats(What, Getter), 430 ( pce_formats(Getter, Names) 431 -> print_message(informational, 432 installation(pce_formats(What, Names))) 433 ; true 434 )). 435 436pce_formats(image, image_save_formats). 437pce_formats(sound, sound_file_extensions). 438pce_formats(video, video_decoders). 439pce_formats(video_writer, video_encoders). 440 441pce_formats(Getter, Names) :- 442 catch(get(@(display), Getter, Chain), _, fail), 443 get(Chain, size, N), 444 findall(Name, ( between(1, N, I), 445 get(Chain, nth1, I, Name) 446 ), Names).
450ssl_version :-
451 current_prolog_flag(ssl_library_version, SSLVersion),
452 print_message(informational, installation(version(SSLVersion))).459jquery_file :- 460 setting(jquery:version, File), 461 ( absolute_file_name(js(File), Path, [access(read), file_errors(fail)]) 462 -> print_message(informational, installation(jquery(found(Path)))) 463 ; print_message(warning, installation(jquery(not_found(File)))) 464 ). 465 466sweep_emacs_module :- 467 with_output_to(string(S), write_sweep_module_location), 468 split_string(S, "\n", "\n", [VersionInfo|Modules]), 469 must_be(oneof(["V 1"]), VersionInfo), 470 ( maplist(check_sweep_lib, Modules) 471 -> print_message(informational, installation(sweep(found(Modules)))) 472 ; print_message(warning, installation(sweep(not_found(Modules)))) 473 ). 474 475check_sweep_lib(Line) :- 476 sub_atom(Line, B, _, A, ' '), 477 sub_atom(Line, 0, B, _, Type), 478 must_be(oneof(['L', 'M']), Type), 479 sub_atom(Line, _, A, 0, Lib), 480 exists_file(Lib). 481 482python_version :- 483 py_call(sys:version, Version), 484 print_message(informational, installation(janus(Version))).
493check_on_path :- 494 current_prolog_flag(executable, EXEFlag), 495 prolog_to_os_filename(EXE, EXEFlag), 496 file_base_name(EXE, Prog), 497 absolute_file_name(EXE, AbsExe, 498 [ access(execute), 499 file_errors(fail) 500 ]), 501 !, 502 prolog_to_os_filename(AbsExe, OsExe), 503 ( absolute_file_name(path(Prog), OnPath, 504 [ access(execute), 505 file_errors(fail) 506 ]) 507 -> ( same_file(EXE, OnPath) 508 -> true 509 ; absolute_file_name(path(Prog), OnPathAny, 510 [ access(execute), 511 file_errors(fail), 512 solutions(all) 513 ]), 514 same_file(EXE, OnPathAny) 515 -> print_message(warning, installation(not_first_on_path(OsExe, OnPath))) 516 ; print_message(warning, installation(not_same_on_path(OsExe, OnPath))) 517 ) 518 ; print_message(warning, installation(not_on_path(OsExe, Prog))) 519 ). 520check_on_path. 521 522 523 /******************************* 524 * RUN TESTS * 525 *******************************/
cmake -DINSTALL_TESTS=ON
Options processed:
false, do not test the packagesWhen running this predicate the working directory must be writeable and allow for writing executable files. This is due to tests for file system interaction and tests for generating stand-alone executables. Note also that due to its side effects, the predicate should not be invoked twice in the same session.
548test_installation :- 549 test_installation([]). 550 551test_installation(Options) :- 552 absolute_file_name(swi(test/test), 553 TestFile, 554 [ access(read), 555 file_errors(fail), 556 file_type(prolog) 557 ]), 558 !, 559 test_installation_run(TestFile, Options). 560test_installation(_Options) :- 561 print_message(warning, installation(testing(no_installed_tests))). 562 563test_installation_run(TestFile, Options) :- 564 ( option(package(_), Options) 565 -> merge_options(Options, 566 [ core(false), 567 subdirs(false) 568 ], TestOptions) 569 ; merge_options(Options, 570 [ packages(true) 571 ], TestOptions) 572 ), 573 load_files(user:TestFile), 574 current_prolog_flag(verbose, Old), 575 setup_call_cleanup( 576 set_prolog_flag(verbose, silent), 577 user:test([], TestOptions), 578 set_prolog_flag(verbose, Old)). 579 580 581 /******************************* 582 * MESSAGES * 583 *******************************/ 584 585:- multifile 586 prolog:message//1. 587 588print_issue(Term) :- 589 assertz(issue(Term)), 590 print_message(warning, Term). 591 592issue_url(Properties, URL) :- 593 Local = Properties.get(url), 594 !, 595 issue_base(Base), 596 atom_concat(Base, Local, URL). 597issue_url(Properties, URL) :- 598 Properties.get(source) = library(Segments), 599 !, 600 path_segments_atom(Segments, Base), 601 file_name_extension(Base, html, URLFile), 602 issue_base(Issues), 603 atom_concat(Issues, URLFile, URL). 604 605prologmessage(installation(Message)) --> 606 message(Message). 607 608message(checking) --> 609 { current_prolog_flag(address_bits, Bits) }, 610 { current_prolog_flag(arch, Arch) }, 611 { current_prolog_flag(home, Home) }, 612 { current_prolog_flag(cpu_count, Cores) }, 613 { current_prolog_flag(build_type, BuildType) -> true ; BuildType = "?" }, 614 [ 'Checking your SWI-Prolog kit for common issues ...'-[], nl, nl ], 615 [ 'Version: ~`.t~24| '-[] ], '$messages':prolog_message(version), [nl], 616 [ 'CMake Build type: ~`.t~24| ~w'-[BuildType] ], [nl], 617 [ 'Address bits: ~`.t~24| ~d'-[Bits] ], [nl], 618 [ 'Architecture: ~`.t~24| ~w'-[Arch] ], [nl], 619 [ 'Installed at: ~`.t~24| ~w'-[Home] ], [nl], 620 [ 'Cores: ~`.t~24| ~w'-[Cores] ], [nl], 621 [ nl ]. 622message(perfect) --> 623 [ nl, 'Congratulations, your kit seems sound and complete!'-[] ]. 624message(imperfect(N)) --> 625 [ 'Found ~w issues.'-[N] ]. 626message(checking(Feature)) --> 627 [ 'Checking ~w ...'-[Feature], flush ]. 628message(missing(Properties)) --> 629 [ at_same_line, '~`.t~48| not present'-[] ], 630 details(Properties). 631message(loading(Source)) --> 632 [ 'Loading ~q ...'-[Source], flush ]. 633message(ok) --> 634 [ at_same_line, '~`.t~48| ok'-[] ]. 635message(optional_not_found(Properties)) --> 636 [ 'Optional ~q ~`.t~48| not present'-[Properties.source] ]. 637message(not_found(Properties)) --> 638 [ '~q ~`.t~48| NOT FOUND'-[Properties.source] ], 639 details(Properties). 640message(failed(Properties, false, [])) --> 641 !, 642 [ at_same_line, '~`.t~48| FAILED'-[] ], 643 details(Properties). 644message(failed(Properties, exception(Ex0), [])) --> 645 !, 646 { strip_stack(Ex0, Ex), 647 message_to_string(Ex, Msg) }, 648 [ '~w'-[Msg] ], 649 details(Properties). 650message(failed(Properties, true, Messages)) --> 651 [ at_same_line, '~`.t~48| FAILED'-[] ], 652 explain(Messages), 653 details(Properties). 654message(archive(What, Names)) --> 655 [ ' Supported ~w: '-[What] ], 656 list_names(Names). 657message(pce_formats(image, Formats)) --> 658 [ ' Images can be saved as: '-[] ], 659 list_names(Formats). 660message(pce_formats(sound, [wav])) --> 661 !, 662 [ ' Sound files that can be loaded: wav (no SDL3_sound)'-[] ]. 663message(pce_formats(sound, Extensions)) --> 664 [ ' Sound files that can be loaded: '-[] ], 665 list_names(Extensions). 666message(pce_formats(video, [])) --> 667 !, 668 [ ' Videos cannot be played (xpce has no video support)'-[] ]. 669message(pce_formats(video, Codecs)) --> 670 [ ' Video codecs that can be played: '-[] ], 671 list_names(Codecs). 672message(pce_formats(video_writer, [])) --> 673 !, 674 [ ' Videos cannot be written (no video encoders)'-[] ]. 675message(pce_formats(video_writer, Codecs)) --> 676 [ ' Video codecs that can be written: '-[] ], 677 list_names(Codecs). 678message(pcre_missing(Features)) --> 679 [ 'Missing libpcre features: '-[] ], 680 list_names(Features). 681message(not_first_on_path(EXE, OnPath)) --> 682 { public_executable(EXE, PublicEXE), 683 file_base_name(EXE, Prog) 684 }, 685 [ 'The first ~w on '-[Prog] ], 'PATH', [ ' is ~p, while '-[OnPath], nl ], 686 [ 'this version is ~p.'-[PublicEXE] ]. 687message(not_same_on_path(EXE, OnPath)) --> 688 { public_executable(EXE, PublicEXE), 689 file_base_name(EXE, Prog) 690 }, 691 [ 'The ~w on '-[Prog] ], 'PATH', [ ' is ~p, while '-[OnPath], nl ], 692 [ 'this version is ~p.'-[PublicEXE] ]. 693message(not_on_path(EXE, Prog)) --> 694 { public_bin_dir(EXE, Dir), 695 prolog_to_os_filename(Dir, OSDir) 696 }, 697 [ 'Could not find ~w on '-[Prog] ], 'PATH', [ '. '-[], nl ], 698 [ 'You may wish to add ~p to '-[OSDir] ], 'PATH', [ '. '-[], nl ]. 699message(jquery(found(Path))) --> 700 [ ' jQuery from ~w'-[Path] ]. 701message(jquery(not_found(File))) --> 702 [ ' Cannot find jQuery (~w)'-[File] ]. 703message(sweep(found(Paths))) --> 704 [ ' GNU-Emacs plugin loads'-[] ], 705 sequence(list_file, Paths). 706message(sweep(not_found(Paths))) --> 707 [ ' Could not find all GNU-Emacs libraries'-[] ], 708 sequence(list_file, Paths). 709message(testing(no_installed_tests)) --> 710 [ ' Runtime testing is not enabled.', nl], 711 [ ' Please recompile the system with INSTALL_TESTS enabled.' ]. 712message(janus(Version)) --> 713 [ ' Python version ~w'-[Version] ]. 714message(ambiguous_autoload(PI, Paths)) --> 715 [ 'The predicate ~p can be autoloaded from multiple libraries:'-[PI]], 716 sequence(list_file, Paths). 717message(version(Version)) --> 718 [ ' Using ~w'-[Version] ]. 719message(lib_version(What, Version)) --> 720 [ ' Using library ~w version ~w'-[What, Version] ]. 721 722public_executable(EXE, PublicProg) :- 723 file_base_name(EXE, Prog), 724 file_directory_name(EXE, ArchDir), 725 file_directory_name(ArchDir, BinDir), 726 file_directory_name(BinDir, Home), 727 file_directory_name(Home, Lib), 728 file_directory_name(Lib, Prefix), 729 atomic_list_concat([Prefix, bin, Prog], /, PublicProg), 730 exists_file(PublicProg), 731 same_file(EXE, PublicProg), 732 !. 733public_executable(EXE, EXE). 734 735public_bin_dir(EXE, Dir) :- 736 public_executable(EXE, PublicEXE), 737 file_directory_name(PublicEXE, Dir). 738 739 740 741'PATH' --> 742 { current_prolog_flag(windows, true) }, 743 !, 744 [ '%PATH%'-[] ]. 745'PATH' --> 746 [ '$PATH'-[] ]. 747 748strip_stack(error(Error, context(prolog_stack(S), Msg)), 749 error(Error, context(_, Msg))) :- 750 nonvar(S). 751strip_stack(Error, Error). 752 753details(Properties) --> 754 { issue_url(Properties, URL), ! 755 }, 756 [ nl, 'See '-[], url(URL) ]. 757details(_) --> []. 758 759explain(Messages) --> 760 { shared_object_error(Messages) }, 761 !, 762 [nl], 763 ( { current_prolog_flag(windows, true) } 764 -> [ 'Cannot load required DLL'-[] ] 765 ; [ 'Cannot load required shared library'-[] ] 766 ). 767explain(Messages) --> 768 print_messages(Messages). 769 (Messages) :- 771 sub_term(Term, Messages), 772 subsumes_term(error(shared_object(open, _Message), _), Term), 773 !. 774 775print_messages([]) --> []. 776print_messages([message(_Term, _Kind, Lines)|T]) --> 777 , [nl], 778 print_messages(T). 779 780list_names([]) --> []. 781list_names([H|T]) --> 782 [ '~w'-[H] ], 783 ( {T==[]} 784 -> [] 785 ; [ ', '-[] ], 786 list_names(T) 787 ). 788 789list_file(File) --> 790 [ nl, ' '-[], url(File) ]. 791 792 793 /******************************* 794 * CONFIG FILES * 795 *******************************/
802check_config_files :- 803 check_config_files(Issues), 804 maplist(print_message(warning), Issues). 805 806check_config_files(Issues) :- 807 findall(Issue, check_config_file(Issue), Issues). 808 809check_config_file(config(Id, move(Type, OldFile, NewFile))) :- 810 old_config(Type, Id, OldFile), 811 access_file(OldFile, exist), 812 \+ ( new_config(Type, Id, NewFile), 813 access_file(NewFile, exist) 814 ), 815 once(new_config(Type, Id, NewFile)). 816check_config_file(config(Id, different(Type, OldFile, NewFile))) :- 817 old_config(Type, Id, OldFile), 818 access_file(OldFile, exist), 819 new_config(Type, Id, NewFile), 820 access_file(NewFile, exist), 821 \+ same_file(OldFile, NewFile).
828update_config_files :- 829 old_config(Type, Id, OldFile), 830 access_file(OldFile, exist), 831 \+ ( new_config(Type, Id, NewFile), 832 access_file(NewFile, exist) 833 ), 834 ( new_config(Type, Id, NewFile), 835 \+ same_file(OldFile, NewFile), 836 create_parent_dir(NewFile) 837 -> catch(rename_file(OldFile, NewFile), E, 838 print_message(warning, E)), 839 print_message(informational, config(Id, moved(Type, OldFile, NewFile))) 840 ), 841 fail. 842update_config_files. 843 844old_config(file, init, File) :- 845 current_prolog_flag(windows, true), 846 win_folder(appdata, Base), 847 atom_concat(Base, '/SWI-Prolog/swipl.ini', File). 848old_config(file, init, File) :- 849 expand_file_name('~/.swiplrc', [File]). 850old_config(directory, lib, Dir) :- 851 expand_file_name('~/lib/prolog', [Dir]). 852old_config(directory, xpce, Dir) :- 853 expand_file_name('~/.xpce', [Dir]). 854old_config(directory, history, Dir) :- 855 expand_file_name('~/.swipl-dir-history', [Dir]). 856old_config(directory, pack, Dir) :- 857 ( catch(expand_file_name('~/lib/swipl/pack', [Dir]), _, fail) 858 ; absolute_file_name(swi(pack), Dir, 859 [ file_type(directory), solutions(all) ]) 860 ). 861 862new_config(file, init, File) :- 863 absolute_file_name(user_app_config('init.pl'), File, 864 [ solutions(all) ]). 865new_config(directory, lib, Dir) :- 866 config_dir(user_app_config(lib), Dir). 867new_config(directory, xpce, Dir) :- 868 config_dir(user_app_config(xpce), Dir). 869new_config(directory, history, Dir) :- 870 config_dir(user_app_config('dir-history'), Dir). 871new_config(directory, pack, Dir) :- 872 config_dir([app_data(pack), swi(pack)], Dir). 873 874config_dir(Aliases, Dir) :- 875 is_list(Aliases), 876 !, 877 ( member(Alias, Aliases), 878 absolute_file_name(Alias, Dir, 879 [ file_type(directory), solutions(all) ]) 880 *-> true 881 ; member(Alias, Aliases), 882 absolute_file_name(Alias, Dir, 883 [ solutions(all) ]) 884 ). 885config_dir(Alias, Dir) :- 886 ( absolute_file_name(Alias, Dir, 887 [ file_type(directory), solutions(all) ]) 888 *-> true 889 ; absolute_file_name(Alias, Dir, 890 [ solutions(all) ]) 891 ). 892 893create_parent_dir(NewFile) :- 894 file_directory_name(NewFile, Dir), 895 create_parent_dir_(Dir). 896 897create_parent_dir_(Dir) :- 898 exists_directory(Dir), 899 '$my_file'(Dir), 900 !. 901create_parent_dir_(Dir) :- 902 file_directory_name(Dir, Parent), 903 Parent \== Dir, 904 create_parent_dir_(Parent), 905 make_directory(Dir). 906 907prologmessage(config(Id, Issue)) --> 908 [ 'Config: '-[] ], 909 config_description(Id), 910 config_issue(Issue). 911 912config_description(init) --> 913 [ '(user initialization file) '-[], nl ]. 914config_description(lib) --> 915 [ '(user library) '-[], nl ]. 916config_description(pack) --> 917 [ '(add-ons) '-[], nl ]. 918config_description(history) --> 919 [ '(command line history) '-[], nl ]. 920config_description(xpce) --> 921 [ '(gui) '-[], nl ]. 922 923config_issue(move(Type, Old, New)) --> 924 [ ' found ~w "~w"'-[Type, Old], nl ], 925 [ ' new location is "~w"'-[New] ]. 926config_issue(moved(Type, Old, New)) --> 927 [ ' found ~w "~w"'-[Type, Old], nl ], 928 [ ' moved to new location "~w"'-[New] ]. 929config_issue(different(Type, Old, New)) --> 930 [ ' found different ~w "~w"'-[Type, Old], nl ], 931 [ ' new location is "~w"'-[New] ]. 932 933 /******************************* 934 * AUTO LOADING * 935 *******************************/
941check_autoload :- 942 findall(Name/Arity, '$in_library'(Name, Arity, _Path), PIs), 943 msort(PIs, Sorted), 944 clumped(Sorted, Clumped), 945 sort(2, >=, Clumped, ClumpedS), 946 ambiguous_autoload(ClumpedS). 947 948ambiguous_autoload([PI-N|T]) :- 949 N > 1, 950 !, 951 warn_ambiguous_autoload(PI), 952 ambiguous_autoload(T). 953ambiguous_autoload(_). 954 955warn_ambiguous_autoload(PI) :- 956 PI = Name/Arity, 957 findall(PlFile, 958 ( '$in_library'(Name, Arity, File), 959 file_name_extension(File, pl, PlFile) 960 ), PlFiles), 961 print_message(warning, installation(ambiguous_autoload(PI, PlFiles)))
Check installation issues and features
This library performs checks on the installed system to verify which optional components are available and whether all libraries that load shared objects/DLLs can be loaded.