[m-rev.] for review: library installation with `mmc --make'
Simon Taylor
stayl at cs.mu.OZ.AU
Sun Jul 7 22:12:59 AEST 2002
Estimated hours taken: 10
Branches: main
Library installation with `mmc --make'.
compiler/make.m:
compiler/make.program_target.m:
Handle `mmc --make lib<module>.install'.
compiler/options.m:
compiler/handle_options.m:
Add an option `--use-grade-subdirs', which causes
all grade-dependenent files to be placed in
`Mercury/<grade>/<ext>s' subdirectories, even
those files that are intended for use by the user.
`--use-grade-subdirs' is not documented because it
is only intended for use in library installation
with `mmc --make' (it doesn't work at all with Mmake).
Documenting it would require documenting (and setting
in stone) the layout of the `Mercury' directory, which
is probably a bad idea.
compiler/modules.m:
compiler/intermod.m:
compiler/make.module_dep_file.m:
compiler/mercury_compile.m:
compiler/mlds_to_c.m:
compiler/trans_opt.m:
Handle `--use-grade-subdirs' in module_name_to_file_name.
Add module_name_to_search_file_name, which should be
used to generate the names of files that might be part
of an installed library. This is needed because installation
and local directory hierarchies have a different layout,
A better long-term fix would be to change things so that
the installation and local directory layouts are the same.
compiler/make.util.m:
compiler/make.dependencies.m:
compiler/make.module_target.m:
Add an extra argument to get_target_timestamp and
get_file_name to specify whether the file should
be searched for.
compiler/options_file.m:
scripts/Mmake.vars.in:
Handle the LIBGRADES and INSTALL_PREFIX make variables.
doc/user_guide.texi:
Remove the statement that library installation is
not supported with `mmc --make'.
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.142
diff -u -u -r1.142 handle_options.m
--- compiler/handle_options.m 1 Jul 2002 09:03:54 -0000 1.142
+++ compiler/handle_options.m 6 Jul 2002 16:48:28 -0000
@@ -61,6 +61,10 @@
:- pred convert_grade_option(string::in, option_table::in, option_table::out)
is semidet.
+ % Produce the grade component of grade-specific
+ % installation directories.
+:- pred grade_directory_component(globals::in, string::out) is det.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -447,6 +451,11 @@
option_implies(make, compile_only, bool(yes)),
option_implies(make, target_code_only, bool(yes)),
+ % This is needed for library installation (the library grades
+ % are built using `--use-grade-subdirs', and assume that
+ % the interface files were built using `--use-subdirs').
+ option_implies(make, use_subdirs, bool(yes)),
+
option_implies(verbose_check_termination, check_termination,bool(yes)),
option_implies(check_termination, termination, bool(yes)),
option_implies(check_termination, warn_missing_trans_opt_files,
@@ -537,6 +546,8 @@
% without checking timestamps.
option_implies(rebuild, make, bool(yes)),
+ option_implies(use_grade_subdirs, use_subdirs, bool(yes)),
+
% --make handles creation of the module dependencies itself,
% and they don't need to be recreated when compiling to C.
option_implies(invoked_by_mmc_make,
@@ -897,31 +908,24 @@
%
globals__io_lookup_accumulating_option(mercury_library_directories,
MercuryLibDirs),
+ globals__io_lookup_string_option(fullarch, FullArch),
+ globals__io_get_globals(Globals),
+ { grade_directory_component(Globals, GradeString) },
(
{ MercuryLibDirs = [_|_] },
- globals__io_lookup_string_option(fullarch, FullArch),
- globals__io_get_globals(Globals),
- { compute_grade(Globals, GradeString) },
{ ExtraLinkLibDirs = list__map(
- (func(MercuryLibDir) =
- dir__make_path_name(MercuryLibDir,
- dir__make_path_name("lib",
- dir__make_path_name(GradeString,
- FullArch)))
- ), MercuryLibDirs) },
+ (func(MercuryLibDir) =
+ MercuryLibDir/"lib"/GradeString/FullArch
+ ), MercuryLibDirs) },
globals__io_lookup_accumulating_option(
link_library_directories, LinkLibDirs),
globals__io_set_option(link_library_directories,
accumulating(LinkLibDirs ++ ExtraLinkLibDirs)),
{ ExtraCIncludeDirs = list__map(
- (func(MercuryLibDir) =
- dir__make_path_name(MercuryLibDir,
- dir__make_path_name("lib",
- dir__make_path_name(GradeString,
- dir__make_path_name(FullArch,
- "inc"))))
- ), MercuryLibDirs) },
+ (func(MercuryLibDir) =
+ MercuryLibDir/"lib"/GradeString/FullArch/"inc"
+ ), MercuryLibDirs) },
globals__io_lookup_accumulating_option(c_include_directory,
CIncludeDirs),
globals__io_set_option(c_include_directory,
@@ -947,6 +951,40 @@
[]
),
+ globals__io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs),
+ ( { UseGradeSubdirs = yes } ->
+ %
+ % With `--use-grade-subdirs', `.opt', `.mih' and `.mh' files
+ % are placed in a directory named
+ % `Mercury/<grade>/<fullarch>/Mercury/<ext>s'.
+ % When searching for a file, module_name_to_file_name
+ % produces `Mercury/<ext>/<module>.ext' so that searches
+ % for installed files work, so we need to add
+ % `--intermod-directory Mercury/<grade>/<fullarch>'
+ % to find the `.opt' files in the current directory.
+ %
+ globals__io_lookup_accumulating_option(intermod_directories,
+ IntermodDirs1),
+ { GradeSubdirIntermodDirs =
+ ["Mercury"/GradeString/FullArch |
+ list__filter(isnt(unify(dir__this_directory)),
+ IntermodDirs1)] },
+ globals__io_set_option(intermod_directories,
+ accumulating(GradeSubdirIntermodDirs)),
+
+ globals__io_lookup_accumulating_option(c_include_directory,
+ CIncludeDirs1),
+ { GradeSubdirCIncludeDirs =
+ ["Mercury"/GradeString/FullArch/"Mercury"/"mhs",
+ "Mercury"/GradeString/FullArch |
+ list__filter(isnt(unify(dir__this_directory)),
+ CIncludeDirs1)] },
+ globals__io_set_option(c_include_directory,
+ accumulating(GradeSubdirCIncludeDirs))
+ ;
+ []
+ ),
+
% --use-opt-files implies --no-warn-missing-opt-files since
% we are expecting some to be missing.
option_implies(use_opt_files, warn_missing_opt_files, bool(no)),
@@ -1231,6 +1269,25 @@
Opt = Option - Data,
map__set(Opts1, Option, Data, Opts2)
)), CompOpts, Opts0, Opts).
+
+grade_directory_component(Globals, Grade) :-
+ compute_grade(Globals, Grade0),
+
+ %
+ % Strip out the `.picreg' part of the grade -- `.picreg' is
+ % implied by the file names (.pic_o vs .o, `.a' vs `.so').
+ %
+ (
+ string__sub_string_search(Grade0,
+ ".picreg", PicRegIndex),
+ string__split(Grade0, PicRegIndex,
+ LeftPart, RightPart0),
+ string__append(".picreg", RightPart, RightPart0)
+ ->
+ Grade = LeftPart ++ RightPart
+ ;
+ Grade = Grade0
+ ).
compute_grade(Globals, Grade) :-
globals__get_options(Globals, Options),
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.122
diff -u -u -r1.122 intermod.m
--- compiler/intermod.m 30 Jun 2002 17:06:18 -0000 1.122
+++ compiler/intermod.m 5 Jul 2002 07:21:41 -0000
@@ -2184,7 +2184,7 @@
maybe_write_string(VeryVerbose, "'...\n"),
maybe_flush_output(VeryVerbose),
- module_name_to_file_name(ModuleToRead, ".opt", no, FileName),
+ module_name_to_search_file_name(ModuleToRead, ".opt", FileName),
prog_io__read_opt_file(FileName, ModuleToRead,
ModuleError, Messages, OptItems),
update_error_status(opt, FileName, ModuleError, Messages,
Index: compiler/make.dependencies.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.dependencies.m,v
retrieving revision 1.6
diff -u -u -r1.6 make.dependencies.m
--- compiler/make.dependencies.m 21 Jun 2002 16:52:46 -0000 1.6
+++ compiler/make.dependencies.m 5 Jul 2002 10:10:03 -0000
@@ -881,7 +881,8 @@
% considered to be up-to-date if they
% exist.
%
- get_target_timestamp(Target, MaybeTimestamp, Info1, Info2),
+ get_target_timestamp(yes, Target,
+ MaybeTimestamp, Info1, Info2),
(
{ MaybeTimestamp = ok(_) },
{ Status = up_to_date }
Index: compiler/make.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.m,v
retrieving revision 1.8
diff -u -u -r1.8 make.m
--- compiler/make.m 22 Jun 2002 19:15:54 -0000 1.8
+++ compiler/make.m 4 Jul 2002 09:26:23 -0000
@@ -369,9 +369,10 @@
ModuleNameStr = ModuleNameStr0,
TargetType0 = misc_target(realclean)
;
- Suffix = ".install"
+ Suffix = ".install",
+ string__append("lib", ModuleNameStr1, ModuleNameStr0)
->
- ModuleNameStr = ModuleNameStr0,
+ ModuleNameStr = ModuleNameStr1,
TargetType0 = misc_target(install_library)
;
fail
Index: compiler/make.module_dep_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.module_dep_file.m,v
retrieving revision 1.4
diff -u -u -r1.4 make.module_dep_file.m
--- compiler/make.module_dep_file.m 21 May 2002 19:04:26 -0000 1.4
+++ compiler/make.module_dep_file.m 5 Jul 2002 07:08:27 -0000
@@ -288,8 +288,8 @@
make_info::in, make_info::out, io__state::di, io__state::uo) is det.
read_module_dependencies(RebuildDeps, ModuleName, Info0, Info) -->
- module_name_to_file_name(ModuleName, module_dep_file_extension,
- no, ModuleDepFile),
+ module_name_to_search_file_name(ModuleName, module_dep_file_extension,
+ ModuleDepFile),
globals__io_lookup_accumulating_option(search_directories, SearchDirs),
io__input_stream(OldInputStream),
search_for_file_returning_dir(SearchDirs, ModuleDepFile, SearchResult),
@@ -452,10 +452,10 @@
read_module_dependencies_remake(RebuildDeps, ModuleName, Msg, Info0, Info) -->
( { RebuildDeps = yes } ->
- module_name_to_file_name(ModuleName,
- module_dep_file_extension, no, ModuleDepsFile),
debug_msg(
(pred(di, uo) is det -->
+ module_name_to_file_name(ModuleName,
+ module_dep_file_extension, no, ModuleDepsFile),
io__write_string("Error reading file `"),
io__write_string(ModuleDepsFile),
io__write_string("rebuilding: "),
Index: compiler/make.module_target.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.module_target.m,v
retrieving revision 1.10
diff -u -u -r1.10 make.module_target.m
--- compiler/make.module_target.m 4 Jul 2002 14:18:07 -0000 1.10
+++ compiler/make.module_target.m 5 Jul 2002 10:10:37 -0000
@@ -169,7 +169,7 @@
%
% Check that the target files exist.
%
- list__map_foldl2(get_target_timestamp, TouchedTargetFiles,
+ list__map_foldl2(get_target_timestamp(no), TouchedTargetFiles,
TargetTimestamps, Info1, Info2),
( { list__member(error(_), TargetTimestamps) } ->
debug_file_msg(TargetFile, "target file does not exist"),
@@ -190,7 +190,7 @@
{ MaybeOldestTimestamp = list__foldl(find_oldest_timestamp,
TouchedFileTimestamps, MaybeOldestTimestamp0) },
- get_file_name(TargetFile, TargetFileName, Info4, Info5),
+ get_file_name(no, TargetFile, TargetFileName, Info4, Info5),
check_dependencies(TargetFileName,
MaybeOldestTimestamp, DepFilesToMake,
DepsResult, Info5, Info)
@@ -396,7 +396,7 @@
MakeInfo = MakeInfo0 ^ file_timestamps :=
map__delete(MakeInfo0 ^ file_timestamps, TouchedFile)
) },
- list__map_foldl2(get_file_name, TouchedTargetFiles,
+ list__map_foldl2(get_file_name(no), TouchedTargetFiles,
TouchedTargetFileNames, Info2, Info3),
{ list__foldl(DeleteTimestamp, TouchedTargetFileNames, Info3, Info4) },
{ list__foldl(DeleteTimestamp, OtherTouchedFiles, Info4, Info) }.
@@ -679,10 +679,10 @@
->
module_name_to_file_name(
foreign_language_module_name(ModuleName, c), ".c",
- no, CCodeFileName),
+ yes, CCodeFileName),
module_name_to_file_name(
foreign_language_module_name(ModuleName, c), ObjExt,
- no, ObjFileName),
+ yes, ObjFileName),
{ ForeignFiles0 =
[foreign_code_file(c, CCodeFileName, ObjFileName) ] }
;
@@ -726,9 +726,9 @@
Language) },
{ ForeignExt = foreign_language_file_extension(Language) }
->
- module_name_to_file_name(ForeignModuleName, ForeignExt, no,
+ module_name_to_file_name(ForeignModuleName, ForeignExt, yes,
ForeignFileName),
- module_name_to_file_name(ForeignModuleName, ".dll", no,
+ module_name_to_file_name(ForeignModuleName, ".dll", yes,
ForeignDLLFileName),
{ ForeignFiles = [foreign_code_file(Language, ForeignFileName,
ForeignDLLFileName)] }
Index: compiler/make.program_target.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.program_target.m,v
retrieving revision 1.7
diff -u -u -r1.7 make.program_target.m
--- compiler/make.program_target.m 22 Jun 2002 19:15:54 -0000 1.7
+++ compiler/make.program_target.m 7 Jul 2002 10:22:38 -0000
@@ -359,20 +359,13 @@
(
{ TargetType = clean },
{ Succeeded = yes },
- list__foldl2(make_clean, AllModules, Info3, Info)
+ list__foldl2(make_module_clean, AllModules, Info3, Info4),
+ remove_init_files(MainModuleName, Info4, Info)
;
{ TargetType = realclean },
{ Succeeded = yes },
- list__foldl2(make_realclean, AllModules, Info3, Info4),
- globals__io_lookup_string_option(executable_file_extension,
- ExeExt),
- globals__io_lookup_string_option(library_extension, LibExt),
- globals__io_lookup_string_option(shared_library_extension,
- SharedLibExt),
-
- list__foldl2(remove_file(MainModuleName),
- [ExeExt, LibExt, SharedLibExt, "_init.c", "_init.o"],
- Info4, Info)
+ make_main_module_realclean(MainModuleName, Info3, Info4),
+ list__foldl2(make_module_realclean, AllModules, Info4, Info)
;
{ TargetType = build_all(ModuleTargetType) },
get_target_modules(ModuleTargetType, AllModules,
@@ -399,7 +392,7 @@
Intermod),
{ Intermod = yes ->
OptFiles = make_dependency_list(AllModules,
- long_interface)
+ intermodule_interface)
;
OptFiles = []
},
@@ -435,14 +428,432 @@
)
;
{ TargetType = install_library },
- { Succeeded = no },
- { error("sorry, not implemented: mmc --make module.install") }
+ make_misc_target(MainModuleName - build_library,
+ LibSucceeded, Info3, Info4),
+ ( { LibSucceeded = yes } ->
+ install_library(MainModuleName, Succeeded, Info4, Info)
+ ;
+ { Info = Info4 },
+ { Succeeded = no }
+ )
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred install_library(module_name::in, bool::out,
+ make_info::in, make_info::out, io__state::di, io__state::uo) is det.
+
+install_library(MainModuleName, Succeeded, Info0, Info) -->
+ find_reachable_local_modules(MainModuleName, DepsSuccess,
+ AllModules0, Info0, Info1),
+ { AllModules = set__to_sorted_list(AllModules0) },
+ make_install_dirs(DirSucceeded, LinkSucceeded),
+ ( { DepsSuccess = yes, DirSucceeded = yes } ->
+ globals__io_lookup_string_option(install_prefix, Prefix),
+
+ { ModulesDir = Prefix/"lib"/"mercury"/"modules" },
+ module_name_to_file_name(MainModuleName, ".init", no, InitFileName),
+ install_file(InitFileName, ModulesDir, InitSucceded),
+
+ list__map_foldl2(install_ints_and_headers(LinkSucceeded), AllModules,
+ IntsSucceeded, Info1, Info2),
+
+ globals__io_get_globals(Globals),
+ { compute_grade(Globals, Grade) },
+ install_library_grade_files(LinkSucceeded, Grade, MainModuleName,
+ AllModules, GradeSucceeded, Info2, Info3),
+ (
+ { InitSucceded = yes },
+ { bool__and_list(IntsSucceeded) = yes },
+ { GradeSucceeded = yes }
+ ->
+ % XXX With Mmake, LIBGRADES is target-specific.
+ globals__io_lookup_accumulating_option(libgrades, LibGrades),
+ globals__io_lookup_bool_option(keep_going, KeepGoing),
+ foldl2_maybe_stop_at_error(KeepGoing,
+ install_library_grade(LinkSucceeded,
+ MainModuleName, AllModules),
+ LibGrades, Succeeded, Info3, Info)
+ ;
+ { Info = Info3 },
+ { Succeeded = no }
+ )
+ ;
+ { Info = Info1 },
+ { Succeeded = no }
+ ).
+
+:- pred install_ints_and_headers(bool::in, module_name::in, bool::out,
+ make_info::in, make_info::out, io__state::di, io__state::uo) is det.
+
+install_ints_and_headers(SubdirLinkSucceeded, ModuleName,
+ Succeeded, Info0, Info) -->
+ get_module_dependencies(ModuleName, MaybeImports, Info0, Info),
+ (
+ { MaybeImports = yes(Imports) },
+ globals__io_lookup_bool_option(intermodule_optimization, Intermod),
+ { Intermod = yes ->
+ % `.int0' files are imported by `.opt' files.
+ Exts =
+ ( Imports ^ children \= [] -> ["int0", "opt"] ; ["opt"] )
+ ;
+ Exts = []
+ },
+
+ globals__io_lookup_string_option(install_prefix, Prefix),
+ { LibDir = Prefix/"lib"/"mercury" },
+ list__map_foldl(
+ install_subdir_file(SubdirLinkSucceeded,
+ LibDir/"ints", ModuleName),
+ ["int", "int2", "int3", "module_dep" | Exts],
+ Results),
+
+ globals__io_get_target(Target),
+ (
+ % `.mh' files are only generated for modules containing
+ % `:- pragma export' declarations.
+ { Target = c ; Target = asm },
+ { Imports ^ contains_foreign_export = contains_foreign_export }
+ ->
+ install_subdir_file(SubdirLinkSucceeded, LibDir/"inc",
+ ModuleName, "mh", HeaderSucceded1),
+
+ % This is needed so that the file will be
+ % found in Mmake's VPATH.
+ install_subdir_file(SubdirLinkSucceeded, LibDir/"ints",
+ ModuleName, "mh", HeaderSucceded2),
+
+ { HeaderSucceded = HeaderSucceded1 `and` HeaderSucceded2 }
+ ;
+ { HeaderSucceded = yes }
+ ),
+ { Succeeded = bool__and_list([HeaderSucceded | Results]) }
+ ;
+ { MaybeImports = no },
+ { Succeeded = no }
+ ).
+
+:- pred install_library_grade(bool::in, module_name::in, list(module_name)::in,
+ string::in, bool::out, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+install_library_grade(LinkSucceeded0, ModuleName, AllModules, Grade,
+ Succeeded, Info0, Info) -->
+ %
+ % Building the library in the new grade is done in a separate
+ % process to make it easier to stop and clean up on an interrupt.
+ %
+ { Cleanup = make_grade_clean(ModuleName, AllModules) },
+ build_with_check_for_interrupt(
+ (pred(GradeSuccess::out, MInfo::in, MInfo::out, di, uo) is det -->
+ call_in_forked_process(
+ (pred(GradeSuccess0::out, di, uo) is det -->
+ install_library_grade_2(LinkSucceeded0,
+ Grade, ModuleName, AllModules,
+ MInfo, GradeSuccess0)
+ ), GradeSuccess)
+ ), Cleanup, Succeeded, Info0, Info).
+
+:- pred install_library_grade_2(bool::in, string::in, module_name::in,
+ list(module_name)::in, make_info::in,
+ bool::out, io__state::di, io__state::uo) is det.
+
+install_library_grade_2(LinkSucceeded0, Grade, ModuleName, AllModules,
+ Info0, Succeeded) -->
+ globals__io_get_globals(Globals),
+
+ %
+ % Set up so that grade-dependent files for the current grade
+ % don't overwrite the files for the default grade.
+ %
+ { OptionArgs0 = Info0 ^ option_args },
+ { OptionArgs = OptionArgs0 ++
+ ["--grade", Grade, "--use-grade-subdirs"] },
+
+ verbose_msg(
+ (pred(di, uo) is det -->
+ io__write_string("Installing grade "),
+ io__write_string(Grade),
+ io__nl
+ )),
+
+ lookup_mmc_options(Info0 ^ options_variables, MaybeMCFlags),
+ (
+ { MaybeMCFlags = yes(MCFlags) },
+ handle_options(MCFlags ++ OptionArgs, OptionsError, _, _, _)
+ ;
+ { MaybeMCFlags = no },
+ % Errors should have been caught before.
+ { error("install_library_grade: bad DEFAULT_MCFLAGS") }
+ ),
+
+ (
+ { OptionsError = yes(OptionsMessage) },
+ usage_error(OptionsMessage),
+ { Succeeded = no }
+ ;
+ { OptionsError = no },
+ %
+ % Remove the grade-dependent targets from the status map
+ % (we need to rebuild them in the new grade).
+ %
+ { StatusMap0 = Info0 ^ dependency_status },
+ { StatusMap = map__from_assoc_list(list__filter(
+ (pred((File - _)::in) is semidet :-
+ \+ (
+ File = target(_ - Target),
+ target_is_grade_or_arch_dependent(Target)
+ )
+ ),
+ map__to_assoc_list(StatusMap0))) },
+ { Info1 = (Info0 ^ dependency_status := StatusMap)
+ ^ option_args := OptionArgs },
+
+ make_misc_target(ModuleName - build_library,
+ LibSucceeded, Info1, Info2),
+ ( { LibSucceeded = yes } ->
+ install_library_grade_files(LinkSucceeded0,
+ Grade, ModuleName, AllModules,
+ Succeeded, Info2, Info3),
+
+ make_grade_clean(ModuleName, AllModules,
+ Info3, _)
+ ;
+ { Succeeded = no }
+ )
+ ),
+ globals__io_set_globals(unsafe_promise_unique(Globals)).
+
+ % Install the `.a', `.so, `.opt' and `.mih' files
+ % for the current grade.
+:- pred install_library_grade_files(bool::in, string::in, module_name::in,
+ list(module_name)::in, bool::out, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+install_library_grade_files(LinkSucceeded0, Grade, ModuleName, AllModules,
+ Succeeded, Info0, Info) -->
+ make_grade_install_dirs(Grade, DirResult, LinkSucceeded1),
+ { LinkSucceeded = LinkSucceeded0 `and` LinkSucceeded1 },
+ ( { DirResult = yes } ->
+ linked_target_file_name(ModuleName, static_library, LibFileName),
+ linked_target_file_name(ModuleName, shared_library, SharedLibFileName),
+
+ globals__io_lookup_string_option(install_prefix, Prefix),
+ globals__io_lookup_string_option(fullarch, FullArch),
+ { GradeLibDir = Prefix/"lib"/"mercury"/"lib"/Grade/FullArch },
+
+ install_file(LibFileName, GradeLibDir, LibSucceded),
+ install_file(SharedLibFileName, GradeLibDir, SharedLibSucceded),
+
+ list__map_foldl2(install_grade_ints_and_headers(LinkSucceeded, Grade),
+ AllModules, IntsHeadersSucceded, Info0, Info),
+ { Succeeded = bool__and_list(
+ [LibSucceded, SharedLibSucceded | IntsHeadersSucceded]) }
+ ;
+ { Succeeded = no },
+ { Info = Info0 }
+ ).
+
+ % Install the `.opt' and `.mih' files for the current grade.
+:- pred install_grade_ints_and_headers(bool::in, string::in, module_name::in,
+ bool::out, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+install_grade_ints_and_headers(LinkSucceeded, Grade, ModuleName,
+ Succeeded, Info0, Info) -->
+ get_module_dependencies(ModuleName, MaybeImports, Info0, Info),
+ (
+ { MaybeImports = yes(Imports) },
+ globals__io_lookup_string_option(install_prefix, Prefix),
+ globals__io_lookup_string_option(fullarch, FullArch),
+ { LibDir = Prefix/"lib"/"mercury" },
+
+ globals__io_get_target(Target),
+ globals__io_lookup_bool_option(highlevel_code, HighLevelCode),
+ (
+ { Target = c, HighLevelCode = yes
+ ; Target = asm,
+ Imports ^ foreign_code = contains_foreign_code(_)
+ }
+ ->
+ { GradeIncDir = LibDir/"lib"/Grade/FullArch/"inc" },
+ install_subdir_file(LinkSucceeded, GradeIncDir,
+ ModuleName, "mih", HeaderSucceded1),
+
+ % This is needed so that the file will be
+ % found in Mmake's VPATH.
+ { IntDir = LibDir/"int" },
+ install_subdir_file(LinkSucceeded, IntDir,
+ ModuleName, "mih", HeaderSucceded2),
+
+ { HeaderSucceded = HeaderSucceded1 `and` HeaderSucceded2 }
+ ;
+ { HeaderSucceded = yes }
+ ),
+
+ globals__io_lookup_bool_option(intermodule_optimization, Intermod),
+ ( { Intermod = yes } ->
+ { GradeIntDir = LibDir/"ints"/Grade },
+ install_subdir_file(LinkSucceeded, GradeIntDir,
+ ModuleName, "opt", OptSucceded)
+ ;
+ { OptSucceded = yes }
+ ),
+ { Succeeded = HeaderSucceded `and` OptSucceded }
+ ;
+ { MaybeImports = no },
+ { Succeeded = no }
+ ).
+
+ % Install a file in the given directory, and in
+ % directory/Mercury/exts if the symlinks for the
+ % subdirectories couldn't be created (e.g. on Windows).
+:- pred install_subdir_file(bool::in, dir_name::in, module_name::in,
+ string::in, bool::out, io__state::di, io__state::uo) is det.
+
+install_subdir_file(SubdirLinkSucceeded, InstallDir,
+ ModuleName, Ext, Succeeded) -->
+ module_name_to_file_name(ModuleName, "." ++ Ext, no, FileName),
+ install_file(FileName, InstallDir, Succeeded1),
+ ( { SubdirLinkSucceeded = no } ->
+ install_file(FileName, InstallDir/"Mercury"/(Ext ++ "s"),
+ Succeeded2),
+ { Succeeded = Succeeded1 `and` Succeeded2 }
+ ;
+ { Succeeded = Succeeded1 }
+ ).
+
+:- pred install_file(file_name::in, dir_name::in, bool::out,
+ io__state::di, io__state::uo) is det.
+
+install_file(FileName, InstallDir, Succeeded) -->
+ verbose_msg(
+ (pred(di, uo) is det -->
+ io__write_string("Installing file "),
+ io__write_string(FileName),
+ io__write_string(" in "),
+ io__write_string(InstallDir),
+ io__nl
+ )),
+ globals__io_lookup_string_option(install_command, InstallCommand),
+ { Command = string__join_list(" ",
+ quote_args([InstallCommand, FileName, InstallDir])) },
+ io__output_stream(OutputStream),
+ invoke_shell_command(OutputStream, verbose, Command, Succeeded).
+
+:- pred make_install_dirs(bool::out, bool::out,
+ io__state::di, io__state::uo) is det.
+
+make_install_dirs(Result, LinkResult) -->
+ globals__io_lookup_string_option(install_prefix, Prefix),
+ { LibDir = Prefix/"lib"/"mercury" },
+ make_directory(LibDir/"inc", Result1),
+ make_directory(LibDir/"modules", Result2),
+
+ { IntsSubdir = LibDir/"ints"/"Mercury" },
+ make_directory(IntsSubdir, Result3),
+
+ { Result4 = Result1 `and` Result2 `and` Result3 },
+
+ { Subdirs = ["int", "int2", "int3",
+ "opt", "trans_opt", "module_dep"] },
+ list__map_foldl(make_install_symlink(IntsSubdir),
+ Subdirs, LinkResults),
+ { LinkResult = bool__and_list(LinkResults) },
+ ( { LinkResult = yes } ->
+ { Result = Result4 }
+ ;
+ list__map_foldl(
+ (pred(Ext::in, MkDirResult::out, di, uo) is det -->
+ make_directory(IntsSubdir/(Ext ++ "s"), MkDirResult)
+ ), Subdirs, MkDirResults),
+ { Result = bool__and_list([Result4 | MkDirResults]) }
).
-:- pred make_clean(module_name::in, make_info::in, make_info::out,
+:- pred make_grade_install_dirs(string::in, bool::out, bool::out,
+ io__state::di, io__state::uo) is det.
+
+make_grade_install_dirs(Grade, Result, LinkResult) -->
+ globals__io_lookup_string_option(install_prefix, Prefix),
+ globals__io_lookup_string_option(fullarch, FullArch),
+ { LibDir = Prefix/"lib"/"mercury" },
+
+ { GradeIntsSubdir = LibDir/"ints"/Grade/"Mercury" },
+ make_directory(GradeIntsSubdir, Result1),
+
+ { GradeIncSubdir = LibDir/"lib"/Grade/FullArch/"inc"/"Mercury" },
+ make_directory(GradeIncSubdir, Result2),
+
+ { Result3 = Result1 `and` Result2 },
+
+ make_install_symlink(GradeIncSubdir, "mih", LinkResult0),
+ list__map_foldl(make_install_symlink(GradeIntsSubdir),
+ ["opt", "trans_opt"], LinkResults),
+ { LinkResult = bool__and_list([LinkResult0 | LinkResults]) },
+ ( { LinkResult = yes } ->
+ { Result = Result3 }
+ ;
+ make_directory(GradeIncSubdir/"mih", Result4),
+ list__map_foldl(
+ (pred(Ext::in, MkDirResult::out, di, uo) is det -->
+ make_directory(GradeIntsSubdir/(Ext ++ "s"),
+ MkDirResult)
+ ), ["opt", "trans_opt"], MkDirResults),
+ { Result = bool__and_list([Result3, Result4 | MkDirResults]) }
+ ).
+
+:- pred make_install_symlink(string::in, string::in, bool::out,
+ io__state::di, io__state::uo) is det.
+
+make_install_symlink(Subdir, Ext, Result) -->
+ { LinkName = Subdir/(Ext ++ "s") },
+ make_symlink("..", LinkName, Result).
+
+:- pred make_symlink(string::in, string::in, bool::out,
+ io__state::di, io__state::uo) is det.
+
+make_symlink(LinkTarget, LinkName, Result) -->
+ io__output_stream(ErrorStream),
+ { string__format("rm -f %s && ln -s %s %s",
+ [s(LinkName), s(LinkTarget), s(LinkName)], Command) },
+ invoke_shell_command(ErrorStream, verbose, Command, Result).
+
+%-----------------------------------------------------------------------------%
+
+ % Clean up grade-dependent files.
+:- pred make_grade_clean(module_name::in, list(module_name)::in,
+ make_info::in, make_info::out, io__state::di, io__state::uo) is det.
+
+make_grade_clean(ModuleName, AllModules, Info0, Info) -->
+ make_main_module_realclean(ModuleName, Info0, Info1),
+ list__foldl2(make_module_clean, AllModules, Info1, Info).
+
+:- pred make_main_module_realclean(module_name::in,
+ make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+make_main_module_realclean(ModuleName, Info0, Info) -->
+ linked_target_file_name(ModuleName, executable, ExeFileName),
+ linked_target_file_name(ModuleName, static_library, LibFileName),
+ linked_target_file_name(ModuleName, shared_library, SharedLibFileName),
+ list__foldl2(remove_file,
+ [ExeFileName, LibFileName, SharedLibFileName],
+ Info0, Info1),
+ remove_file(ModuleName, ".init", Info1, Info2),
+ remove_init_files(ModuleName, Info2, Info).
+
+:- pred remove_init_files(module_name::in, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+remove_init_files(ModuleName, Info0, Info) -->
+ globals__io_lookup_string_option(object_file_extension, ObjExt),
+ list__foldl2(remove_file(ModuleName), ["_init.c", "_init" ++ ObjExt],
+ Info0, Info).
+
+:- pred make_module_clean(module_name::in, make_info::in, make_info::out,
io__state::di, io__state::uo) is det.
-make_clean(ModuleName, Info0, Info) -->
+make_module_clean(ModuleName, Info0, Info) -->
list__foldl2(remove_target_file(ModuleName),
[errors, c_code, c_header(mih),
object_code(pic), object_code(non_pic),
@@ -451,10 +862,8 @@
],
Info0, Info1),
- globals__io_lookup_string_option(object_file_extension, ObjExt),
list__foldl2(remove_file(ModuleName),
- ["_init.c", "_init" ++ ObjExt, ".used", ".prof",
- ".derived_schema", ".base_schema"],
+ [".used", ".prof", ".derived_schema", ".base_schema"],
Info1, Info2),
get_module_dependencies(ModuleName, MaybeImports, Info2, Info3),
@@ -474,23 +883,17 @@
{ Info = Info3 }
).
-:- pred make_realclean(module_name::in, make_info::in, make_info::out,
+:- pred make_module_realclean(module_name::in, make_info::in, make_info::out,
io__state::di, io__state::uo) is det.
-make_realclean(ModuleName, Info0, Info) -->
- make_clean(ModuleName, Info0, Info1),
+make_module_realclean(ModuleName, Info0, Info) -->
+ make_module_clean(ModuleName, Info0, Info1),
list__foldl2(remove_target_file(ModuleName),
[private_interface, long_interface, short_interface,
unqualified_short_interface, intermodule_interface,
aditi_code, c_header(mh)
],
Info1, Info2),
- remove_file(ModuleName, module_dep_file_extension, Info2, Info3),
- linked_target_file_name(ModuleName, executable, ExeFileName),
- linked_target_file_name(ModuleName, static_library, LibFileName),
- linked_target_file_name(ModuleName, shared_library, SharedLibFileName),
- list__foldl2(remove_file,
- [ExeFileName, LibFileName, SharedLibFileName],
- Info3, Info).
+ remove_file(ModuleName, module_dep_file_extension, Info2, Info).
%-----------------------------------------------------------------------------%
Index: compiler/make.util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.util.m,v
retrieving revision 1.8
diff -u -u -r1.8 make.util.m
--- compiler/make.util.m 21 Jun 2002 16:52:46 -0000 1.8
+++ compiler/make.util.m 5 Jul 2002 10:09:13 -0000
@@ -92,12 +92,21 @@
maybe_error(timestamp)::out, make_info::in, make_info::out,
io__state::di, io__state::uo) is det.
+ % get_target_timestamp(Search, TargetFile, Timestamp)
+ %
% Find the timestamp for the given target file.
-:- pred get_target_timestamp(target_file::in, maybe_error(timestamp)::out,
- make_info::in, make_info::out, io__state::di, io__state::uo) is det.
+ % `Search' should be `yes' if the file could be part of an
+ % installed library.
+:- pred get_target_timestamp(bool::in, target_file::in,
+ maybe_error(timestamp)::out, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+ % get_file_name(Search, TargetFile, FileName).
+ %
% Compute a file name for the given target file.
-:- pred get_file_name(target_file::in, file_name::out,
+ % `Search' should be `yes' if the file could be part of an
+ % installed library.
+:- pred get_file_name(bool::in, target_file::in, file_name::out,
make_info::in, make_info::out, io__state::di, io__state::uo) is det.
% Find the timestamp of the first file matching the given
@@ -148,6 +157,8 @@
% given target type, if one exists.
:- func timestamp_extension(globals, module_target_type) = string is semidet.
+:- pred target_is_grade_or_arch_dependent(module_target_type::in) is semidet.
+
%-----------------------------------------------------------------------------%
% Debugging, verbose and error messages.
@@ -279,9 +290,12 @@
% --invoked-by-mmc-make disables reading DEFAULT_MCFLAGS
% from the environment (DEFAULT_MCFLAGS is included in
% OptionArgs) and generation of `.d' files.
+ % --use-subdirs is needed because the code to install
+ % libraries uses `--use-grade-subdirs' and assumes the
+ % interface files were built with `--use-subdirs'.
{ AllOptionArgs = list__condense([
["--invoked-by-mmc-make" | OptionArgs],
- Info0 ^ option_args, ExtraOptions]) },
+ Info0 ^ option_args, ExtraOptions, ["--use-subdirs"]]) },
handle_options(AllOptionArgs, OptionsError, _, _, _),
(
{ OptionsError = yes(OptionsMessage) },
@@ -420,7 +434,7 @@
),
get_file_timestamp(SearchDirs, FileName, MaybeTimestamp, Info0, Info).
get_dependency_timestamp(target(Target), MaybeTimestamp, Info0, Info) -->
- get_target_timestamp(Target, MaybeTimestamp0, Info0, Info),
+ get_target_timestamp(yes, Target, MaybeTimestamp0, Info0, Info),
{ Target = _ - c_header(mih), MaybeTimestamp0 = ok(_) ->
% Don't rebuild the `.o' file if an irrelevant part of a
% `.mih' file has changed. If a relevant part of a `.mih'
@@ -432,9 +446,14 @@
MaybeTimestamp = MaybeTimestamp0
}.
-get_target_timestamp(ModuleName - FileType, MaybeTimestamp, Info0, Info) -->
- get_file_name(ModuleName - FileType, FileName, Info0, Info1),
- get_search_directories(FileType, SearchDirs),
+get_target_timestamp(Search, ModuleName - FileType, MaybeTimestamp,
+ Info0, Info) -->
+ get_file_name(Search, ModuleName - FileType, FileName, Info0, Info1),
+ ( { Search = yes } ->
+ get_search_directories(FileType, SearchDirs)
+ ;
+ { SearchDirs = [dir__this_directory] }
+ ),
get_file_timestamp(SearchDirs, FileName, MaybeTimestamp0,
Info1, Info2),
(
@@ -464,7 +483,7 @@
{ Info = Info2 }
).
-get_file_name(ModuleName - FileType, FileName, Info0, Info) -->
+get_file_name(Search, ModuleName - FileType, FileName, Info0, Info) -->
( { FileType = source } ->
%
% In some cases the module name won't match the file
@@ -486,8 +505,14 @@
;
{ Info = Info0 },
globals__io_get_globals(Globals),
- module_name_to_file_name(ModuleName,
- target_extension(Globals, FileType), no, FileName)
+ { Ext = target_extension(Globals, FileType) },
+ ( { Search = yes } ->
+ module_name_to_search_file_name(ModuleName,
+ Ext, FileName)
+ ;
+ module_name_to_file_name(ModuleName,
+ Ext, no, FileName)
+ )
).
get_file_timestamp(SearchDirs, FileName, MaybeTimestamp, Info0, Info) -->
@@ -643,6 +668,29 @@
search_for_file_type(java_code) = no.
search_for_file_type(asm_code(_)) = no.
search_for_file_type(object_code(_)) = no.
+
+target_is_grade_or_arch_dependent(Target) :-
+ target_is_grade_or_arch_dependent(Target, yes).
+
+:- pred target_is_grade_or_arch_dependent(module_target_type::in,
+ bool::out) is det.
+
+target_is_grade_or_arch_dependent(source, no).
+target_is_grade_or_arch_dependent(errors, no).
+target_is_grade_or_arch_dependent(private_interface, no).
+target_is_grade_or_arch_dependent(long_interface, no).
+target_is_grade_or_arch_dependent(short_interface, no).
+target_is_grade_or_arch_dependent(unqualified_short_interface, no).
+target_is_grade_or_arch_dependent(intermodule_interface, yes).
+target_is_grade_or_arch_dependent(aditi_code, no).
+target_is_grade_or_arch_dependent(c_header(mh), no).
+target_is_grade_or_arch_dependent(c_header(mih), yes).
+target_is_grade_or_arch_dependent(c_code, yes).
+target_is_grade_or_arch_dependent(il_code, yes).
+target_is_grade_or_arch_dependent(il_asm, yes).
+target_is_grade_or_arch_dependent(java_code, yes).
+target_is_grade_or_arch_dependent(asm_code(_), yes).
+target_is_grade_or_arch_dependent(object_code(_), yes).
%-----------------------------------------------------------------------------%
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.256
diff -u -u -r1.256 mercury_compile.m
--- compiler/mercury_compile.m 26 Jun 2002 08:31:23 -0000 1.256
+++ compiler/mercury_compile.m 6 Jul 2002 15:19:18 -0000
@@ -365,7 +365,7 @@
{ file_name_to_module_name(Module, ModuleName) },
globals__io_lookup_bool_option(pic, Pic),
{ AsmExt = (Pic = yes -> ".pic_s" ; ".s") },
- module_name_to_file_name(ModuleName, AsmExt, no,
+ module_name_to_file_name(ModuleName, AsmExt, yes,
AsmFile),
(
{ ModuleName \= FirstModuleName }
@@ -919,7 +919,7 @@
:- mode module_to_link(in, out, di, uo) is det.
module_to_link(ModuleName - _Items, ModuleToLink) -->
- module_name_to_file_name(ModuleName, "", no, ModuleToLink).
+ { module_name_to_file_name(ModuleName, ModuleToLink) }.
%-----------------------------------------------------------------------------%
@@ -1681,8 +1681,8 @@
{ UpdateStatus = yes }
; { UseOptFiles = yes } ->
{ module_info_name(HLDS0, ModuleName) },
- module_name_to_file_name(ModuleName,
- ".opt", no, OptName),
+ module_name_to_search_file_name(ModuleName,
+ ".opt", OptName),
search_for_file(IntermodDirs, OptName, Found),
( { Found = ok(_) } ->
{ UpdateStatus = yes },
@@ -3320,8 +3320,8 @@
Include) -->
(
{ Lang = c },
- module_name_to_file_name(ModuleName, ".mh",
- no, HeaderFileName),
+ module_name_to_search_file_name(ModuleName, ".mh",
+ HeaderFileName),
{ string__append_list(
["#include """, HeaderFileName, """\n"],
IncludeString) },
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.132
diff -u -u -r1.132 mlds_to_c.m
--- compiler/mlds_to_c.m 21 Jun 2002 13:26:42 -0000 1.132
+++ compiler/mlds_to_c.m 5 Jul 2002 07:18:22 -0000
@@ -191,7 +191,7 @@
unexpected(this_file, "foreign import in C backend")
},
- module_name_to_file_name(ModuleName, HeaderExt, no, HeaderFile),
+ module_name_to_search_file_name(ModuleName, HeaderExt, HeaderFile),
io__write_strings(["#include """, HeaderFile, """\n"]).
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.239
diff -u -u -r1.239 modules.m
--- compiler/modules.m 30 Jun 2002 17:06:33 -0000 1.239
+++ compiler/modules.m 6 Jul 2002 16:42:53 -0000
@@ -61,8 +61,8 @@
%
% Currently we use the convention that the module
% `foo:bar:baz' should be named `foo.bar.baz.m',
- % but eventually we will also allow other file
- % naming conventions.
+ % and allow other naming conventions with the
+ % `-f' option.
%
% Note that this predicate is also used to create
% some "phony" Makefile targets that do not have
@@ -72,6 +72,30 @@
io__state, io__state).
:- mode module_name_to_file_name(in, in, in, out, di, uo) is det.
+ % module_name_to_search_file_name(Module, Extension, FileName):
+ %
+ % As above, but for a file which might be in an installed
+ % library, not the current directory.
+ %
+ % With `--use-grade-subdirs', the current directory's `.mih'
+ % files are in `Mercury/<grade>/<arch>/Mercury/mihs', and those
+ % for installed libraries are in
+ % `<prefix>/lib/mercury/lib/<grade>/<arch>/inc/Mercury/mihs'.
+ %
+ % handle_options.m sets up the `--c-include-directory' options
+ % so that the name `Mercury/mihs/<module>.mih' should be used
+ % in a context which requires searching for the `.mih files,
+ % for example in a C file.
+ %
+ % module_name_to_file_name would return
+ % `Mercury/<grade>/<arch>/Mercury/mihs/<module>.mihs',
+ % which would be used when writing or removing the
+ % `.mih' file.
+ %
+:- pred module_name_to_search_file_name(module_name, string, file_name,
+ io__state, io__state).
+:- mode module_name_to_search_file_name(in, in, out, di, uo) is det.
+
% module_name_to_lib_file_name(Prefix, Module, Extension, MkDir,
% FileName):
% Like module_name_to_file_name, but also allows a prefix.
@@ -119,6 +143,10 @@
:- pred file_name_to_module_name(file_name, module_name).
:- mode file_name_to_module_name(in, out) is det.
+ % convert a module name to a file name stem (e.g. foo.bar.baz).
+:- pred module_name_to_file_name(module_name, file_name).
+:- mode module_name_to_file_name(in, out) is det.
+
% Convert a module name to something that is suitable
% for use as a variable name in makefiles.
:- pred module_name_to_make_var_name(module_name, string).
@@ -650,9 +678,12 @@
:- pred update_interface(string, io__state, io__state).
:- mode update_interface(in, di, uo) is det.
- % make_directory(Dir)
+ % make_directory(Dir, Succeeded)
%
% Make the directory Dir and all its parents.
+:- pred make_directory(string, bool, io__state, io__state).
+:- mode make_directory(in, out, di, uo) is det.
+
:- pred make_directory(string, io__state, io__state).
:- mode make_directory(in, di, uo) is det.
@@ -678,7 +709,7 @@
:- implementation.
:- import_module ll_backend__llds_out, hlds__passes_aux, parse_tree__prog_out.
:- import_module parse_tree__prog_util, parse_tree__mercury_to_mercury.
-:- import_module parse_tree__prog_io_util, libs__options.
+:- import_module parse_tree__prog_io_util, libs__options, libs__handle_options.
:- import_module parse_tree__source_file_map.
:- import_module parse_tree__module_qual, backend_libs__foreign.
:- import_module recompilation__version.
@@ -760,7 +791,17 @@
mercury_std_library_module("type_desc").
mercury_std_library_module("varset").
+module_name_to_search_file_name(ModuleName, Ext, FileName) -->
+ module_name_to_file_name(ModuleName, Ext, yes, no, FileName).
+
module_name_to_file_name(ModuleName, Ext, MkDir, FileName) -->
+ module_name_to_file_name(ModuleName, Ext, no, MkDir, FileName).
+
+:- pred module_name_to_file_name(module_name, string, bool, bool, file_name,
+ io__state, io__state).
+:- mode module_name_to_file_name(in, in, in, in, out, di, uo) is det.
+
+module_name_to_file_name(ModuleName, Ext, Search, MkDir, FileName) -->
( { Ext = ".m" } ->
% Look up the module in the module->file mapping.
source_file_map__lookup_module_source_file(ModuleName,
@@ -769,13 +810,14 @@
{ prog_out__sym_name_to_string(ModuleName,
".", BaseFileName) },
{ string__append_list([BaseFileName, Ext], BaseName) },
- choose_file_name(ModuleName, BaseName, Ext, MkDir, FileName)
+ choose_file_name(ModuleName, BaseName, Ext,
+ Search, MkDir, FileName)
).
module_name_to_lib_file_name(Prefix, ModuleName, Ext, MkDir, FileName) -->
{ prog_out__sym_name_to_string(ModuleName, ".", BaseFileName) },
{ string__append_list([Prefix, BaseFileName, Ext], BaseName) },
- choose_file_name(ModuleName, BaseName, Ext, MkDir, FileName).
+ choose_file_name(ModuleName, BaseName, Ext, no, MkDir, FileName).
fact_table_file_name(ModuleName, FactTableFileName, Ext, FileName) -->
extra_link_obj_file_name(ModuleName, FactTableFileName, Ext, FileName).
@@ -789,14 +831,16 @@
:- mode extra_link_obj_file_name(in, in, in, out, di, uo) is det.
extra_link_obj_file_name(ModuleName, ExtraLinkObjName, Ext, FileName) -->
{ string__append(ExtraLinkObjName, Ext, BaseName) },
- choose_file_name(ModuleName, BaseName, Ext, no, FileName).
+ choose_file_name(ModuleName, BaseName, Ext, no, no, FileName).
-:- pred choose_file_name(module_name, string, string, bool, file_name,
+:- pred choose_file_name(module_name, string, string, bool, bool, file_name,
io__state, io__state).
-:- mode choose_file_name(in, in, in, in, out, di, uo) is det.
+:- mode choose_file_name(in, in, in, in, in, out, di, uo) is det.
-choose_file_name(_ModuleName, BaseName, Ext, MkDir, FileName) -->
+choose_file_name(_ModuleName, BaseName, Ext, Search, MkDir, FileName) -->
globals__io_lookup_bool_option(use_subdirs, UseSubdirs),
+ globals__io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs),
+ globals__io_get_globals(Globals),
( { UseSubdirs = no } ->
{ FileName = BaseName }
;
@@ -806,6 +850,23 @@
% output files intended for use by the user,
% and phony Mmake targets names go in the current directory
%
+ \+ {
+ UseGradeSubdirs = yes,
+ file_is_arch_or_grade_dependent(Globals, Ext),
+
+ %
+ % If we're searching for (rather than writing)
+ % a `.mh' file, use the plain file name. This is
+ % so that searches for files in installed libraries
+ % will work. `--c-include-directory' is set so
+ % that searches for files in the current directory
+ % will work.
+ %
+ \+ (
+ Search = yes,
+ ( Ext = ".mh" ; Ext = ".mh.tmp" )
+ )
+ },
{
% executable files
( Ext = ""
@@ -939,20 +1000,16 @@
->
string__append(ExtName, "s", SubDirName)
;
+ Ext = ""
+ ->
+ SubDirName = "bin"
+ ;
string__append_list(["unknown extension `", Ext, "'"],
ErrorMsg),
error(ErrorMsg)
},
- { dir__directory_separator(SlashChar) },
- { string__char_to_string(SlashChar, Slash) },
- { string__append_list(["Mercury", Slash, SubDirName],
- DirName) },
- ( { MkDir = yes } ->
- make_directory(DirName)
- ;
- []
- ),
- { string__append_list([DirName, Slash, BaseName], FileName) }
+ make_file_name(SubDirName, Search, MkDir,
+ BaseName, Ext, FileName)
).
module_name_to_split_c_file_name(ModuleName, Num, Ext, FileName) -->
@@ -973,19 +1030,134 @@
file_name_to_module_name(FileName, ModuleName) :-
string_to_sym_name(FileName, ".", ModuleName).
+module_name_to_file_name(ModuleName, FileName) :-
+ prog_out__sym_name_to_string(ModuleName, ".", FileName).
+
module_name_to_make_var_name(ModuleName, MakeVarName) :-
prog_out__sym_name_to_string(ModuleName, ".", MakeVarName).
make_directory(DirName) -->
+ make_directory(DirName, _Result).
+
+make_directory(DirName, Result) -->
( { dir__this_directory(DirName) } ->
- []
+ { Result = yes }
;
- { make_command_string(string__format(
- "[ -d %s ] || mkdir -p %s",
- [s(DirName), s(DirName)]), forward, Command) },
- io__call_system(Command, _Result)
+ { string__format("[ -d %s ] || mkdir -p %s",
+ [s(DirName), s(DirName)], Command) },
+ io__output_stream(ErrorStream),
+ invoke_shell_command(ErrorStream, verbose, Command, Result)
).
+:- pred make_file_name(dir_name, bool, bool, file_name, string,
+ file_name, io__state, io__state).
+:- mode make_file_name(in, in, in, in, in, out, di, uo) is det.
+
+make_file_name(SubDirName, Search, MkDir, BaseName, Ext, FileName) -->
+ globals__io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs),
+ globals__io_lookup_string_option(fullarch, FullArch),
+ globals__io_get_globals(Globals),
+ {
+ UseGradeSubdirs = yes,
+ file_is_arch_or_grade_dependent(Globals, Ext),
+
+ %
+ % If we're searching for (rather than writing) the file,
+ % just search in Mercury/<ext>s. This is so that searches
+ % for files in installed libraries work.
+ % `--intermod-directories' and `--c-include-directories'
+ % are set so this will work.
+ %
+ \+ (
+ Search = yes,
+ ( Ext = ".opt" ; Ext = ".mih" )
+ )
+ ->
+ grade_directory_component(Globals, Grade),
+
+ % The extra "Mercury" is needed so we can use
+ % `--intermod-directory Mercury/<grade>/<fullarch>' and
+ % `--c-include Mercury/<grade>/<fullarch>' to find
+ % the local `.opt' and `.mih' files without messing
+ % up the search for the files for installed libraries.
+ DirName = "Mercury"/Grade/FullArch/"Mercury"/SubDirName
+ ;
+ DirName = "Mercury"/SubDirName
+ },
+ ( { MkDir = yes } ->
+ make_directory(DirName)
+ ;
+ []
+ ),
+ { FileName = DirName/BaseName }.
+
+:- pred file_is_arch_or_grade_dependent(globals, string).
+:- mode file_is_arch_or_grade_dependent(in, in) is semidet.
+
+file_is_arch_or_grade_dependent(_, Ext) :-
+ file_is_arch_or_grade_dependent_2(Ext).
+file_is_arch_or_grade_dependent(Globals, Ext0) :-
+ string__append(Ext, ".tmp", Ext0), % for mercury_update_interface.
+ file_is_arch_or_grade_dependent(Globals, Ext).
+file_is_arch_or_grade_dependent(Globals, Ext) :-
+ globals__lookup_string_option(Globals, executable_file_extension, Ext).
+file_is_arch_or_grade_dependent(Globals, Ext) :-
+ globals__lookup_string_option(Globals, object_file_extension, ObjExt),
+ ( Ext = ObjExt
+ ; Ext = "_init" ++ ObjExt
+ ).
+file_is_arch_or_grade_dependent(Globals, Ext) :-
+ globals__lookup_string_option(Globals, pic_object_file_extension, Ext).
+file_is_arch_or_grade_dependent(Globals, Ext) :-
+ globals__lookup_string_option(Globals, library_extension, LibExt),
+ ( Ext = LibExt
+ ; Ext = ".split" ++ LibExt
+ ).
+file_is_arch_or_grade_dependent(Globals, Ext) :-
+ globals__lookup_string_option(Globals, shared_library_extension, Ext).
+
+:- pred file_is_arch_or_grade_dependent_2(string).
+:- mode file_is_arch_or_grade_dependent_2(in) is semidet.
+
+ % The `.used' file isn't grade dependent itself, but it contains
+ % information collected while compiling a grade-dependent
+ % `.c', `il', etc file.
+file_is_arch_or_grade_dependent_2(".used").
+file_is_arch_or_grade_dependent_2(".opt").
+file_is_arch_or_grade_dependent_2(".optdate").
+file_is_arch_or_grade_dependent_2(".trans_opt").
+file_is_arch_or_grade_dependent_2(".trans_opt_date").
+file_is_arch_or_grade_dependent_2(".mih").
+
+ % This isn't true (.mh files are the same in all grades)
+ % but we need to generate the `.mh' files in a sub-directory
+ % so that we don't need to pass `--c-include-directory .' to mmc,
+ % which would resut in the `.mih' files for the default grade
+ % being found, rather than those for the current grade, when
+ % installing a library.
+file_is_arch_or_grade_dependent_2(".mh").
+file_is_arch_or_grade_dependent_2(".c").
+file_is_arch_or_grade_dependent_2(".c_date").
+file_is_arch_or_grade_dependent_2(".s").
+file_is_arch_or_grade_dependent_2(".s_date").
+file_is_arch_or_grade_dependent_2(".pic_s").
+file_is_arch_or_grade_dependent_2(".pic_s_date").
+file_is_arch_or_grade_dependent_2(".il").
+file_is_arch_or_grade_dependent_2(".il_date").
+file_is_arch_or_grade_dependent_2(".java").
+file_is_arch_or_grade_dependent_2(".java_date").
+file_is_arch_or_grade_dependent_2(".class").
+file_is_arch_or_grade_dependent_2(".dir").
+file_is_arch_or_grade_dependent_2(".num_split").
+file_is_arch_or_grade_dependent_2(".dll").
+file_is_arch_or_grade_dependent_2(".$A").
+file_is_arch_or_grade_dependent_2(".a").
+file_is_arch_or_grade_dependent_2(".split.$A").
+file_is_arch_or_grade_dependent_2(".split.a").
+file_is_arch_or_grade_dependent_2(".split").
+file_is_arch_or_grade_dependent_2("_init.c").
+file_is_arch_or_grade_dependent_2("_init.$O").
+
%-----------------------------------------------------------------------------%
% Read in the .int3 files that the current module depends on,
@@ -2258,8 +2430,8 @@
%
have_source_file_map(HaveMap),
{ HaveMap = yes,
- prog_out__sym_name_to_string(
- SourceFileModuleName, ".", ModuleArg)
+ module_name_to_file_name(SourceFileModuleName,
+ ModuleArg)
; HaveMap = no,
ModuleArg = SourceFileName
},
@@ -2361,7 +2533,7 @@
% Also add the variable ILASM_KEYFLAG-<module> which
% is used to build the command line for ilasm.
( { Target = il, SignAssembly = yes } ->
- { prog_out__sym_name_to_string(ModuleName, ".",
+ { module_name_to_make_var_name(ModuleName,
ModuleNameString) },
module_name_to_file_name(ModuleName, ".il",
no, IlFileName),
@@ -2572,8 +2744,8 @@
ModuleName, ForeignLang) },
{ ForeignExt = foreign_language_file_extension(ForeignLang) }
->
- module_name_to_file_name(ForeignModuleName, "", no,
- ForeignModuleNameString),
+ { module_name_to_make_var_name(ForeignModuleName,
+ ForeignModuleNameString) },
module_name_to_file_name(ForeignModuleName, ForeignExt, no,
ForeignFileName),
module_name_to_file_name(ModuleName, ".il", no, IlFileName),
@@ -2629,7 +2801,7 @@
module_name::in, string::in, io__state::di, io__state::uo) is det.
write_subdirs_shorthand_rule(DepStream, ModuleName, Ext) -->
- { prog_out__sym_name_to_string(ModuleName, ".", ModuleStr) },
+ { module_name_to_file_name(ModuleName, ModuleStr) },
module_name_to_file_name(ModuleName, Ext, no, Target),
{ ShorthandTarget = ModuleStr ++ Ext },
io__write_string(DepStream, ".PHONY: "),
@@ -2824,7 +2996,7 @@
),
{ is_bool(Found) },
( { Found = no } ->
- module_name_to_file_name(Dep, Suffix, no, OptName),
+ module_name_to_search_file_name(Dep, Suffix, OptName),
search_for_file(IntermodDirs, OptName, Result2),
( { Result2 = ok(_) } ->
{ OptDeps = [Dep | OptDeps1] },
@@ -4928,7 +5100,12 @@
read_mod_2(IgnoreErrors, ModuleName,
Extension, Descr, Search, MaybeOldTimestamp,
ReturnTimestamp, Items, Error, FileName, MaybeTimestamp) -->
- module_name_to_file_name(ModuleName, Extension, no, FileName0),
+ ( { Search = yes } ->
+ module_name_to_search_file_name(ModuleName,
+ Extension, FileName0)
+ ;
+ module_name_to_file_name(ModuleName, Extension, no, FileName0)
+ ),
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
maybe_write_string(VeryVerbose, "% "),
maybe_write_string(VeryVerbose, Descr),
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.376
diff -u -u -r1.376 options.m
--- compiler/options.m 2 Jul 2002 06:19:37 -0000 1.376
+++ compiler/options.m 6 Jul 2002 16:09:34 -0000
@@ -551,6 +551,7 @@
; options_files
; options_search_directories
; use_subdirs
+ ; use_grade_subdirs
% Miscellaneous Options
; search_directories
@@ -1091,6 +1092,7 @@
options_files - accumulating(["Mercury.options"]),
options_search_directories - accumulating(["."]),
use_subdirs - bool(no),
+ use_grade_subdirs - bool(no),
search_directories - accumulating(["."]),
intermod_directories - accumulating([]),
use_search_directories_for_intermod
@@ -1670,6 +1672,7 @@
long_option("options-file", options_files).
long_option("options-search-directory", options_search_directories).
long_option("use-subdirs", use_subdirs).
+long_option("use-grade-subdirs", use_grade_subdirs).
long_option("search-directory", search_directories).
long_option("intermod-directory", intermod_directories).
long_option("use-search-directories-for-intermod",
@@ -3462,6 +3465,13 @@
"--use-subdirs",
"\tGenerate intermediate files in a `Mercury' subdirectory,",
"\trather than generating them in the current directory."
+
+ % `--use-grade-subdirs' is not documented because it
+ % is only intended for use in library installation
+ % with `mmc --make' (it doesn't work at all with Mmake).
+ % Documenting it would require documenting (and setting
+ % in stone) the layout of the `Mercury' directory, which
+ % is probably a bad idea.
]).
:- pred options_help_misc(io__state::di, io__state::uo) is det.
Index: compiler/options_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options_file.m,v
retrieving revision 1.8
diff -u -u -r1.8 options_file.m
--- compiler/options_file.m 25 May 2002 13:25:09 -0000 1.8
+++ compiler/options_file.m 7 Jul 2002 10:00:57 -0000
@@ -762,6 +762,8 @@
; c2init_args
; libraries
; lib_dirs
+ ; lib_grades
+ ; install_prefix
.
:- func options_variable_types = list(options_variable_type).
@@ -773,7 +775,8 @@
[grade_flags, mmc_flags, c_flags, java_flags,
ilasm_flags, csharp_flags, mcpp_flags,
ml_objs, lib_dirs, ml_flags, ld_flags,
- libraries, ml_libs, c2init_args].
+ libraries, ml_libs, c2init_args,
+ lib_grades, install_prefix].
:- func options_variable_name(options_variable_type) = string.
@@ -792,6 +795,8 @@
options_variable_name(c2init_args) = "C2INITARGS".
options_variable_name(libraries) = "LIBRARIES".
options_variable_name(lib_dirs) = "LIB_DIRS".
+options_variable_name(lib_grades) = "LIBGRADES".
+options_variable_name(install_prefix) = "INSTALL_PREFIX".
:- func options_variable_type_is_target_specific(options_variable_type) = bool.
@@ -810,6 +815,9 @@
options_variable_type_is_target_specific(c2init_args) = yes.
options_variable_type_is_target_specific(libraries) = yes.
options_variable_type_is_target_specific(lib_dirs) = no.
+ % XXX With Mmake, LIBGRADES is target specific.
+options_variable_type_is_target_specific(lib_grades) = no.
+options_variable_type_is_target_specific(install_prefix) = no.
:- func convert_to_mmc_options(pair(options_variable_type, list(string)))
= list(string).
@@ -820,22 +828,26 @@
MMCOptionType = mmc_flags,
OptionsStrings = VariableValue
;
- MMCOptionType = option(not_split, OptionName),
- OptionsStrings = [OptionName,
+ MMCOptionType = option(not_split, InitialOptions, OptionName),
+ OptionsStrings = InitialOptions ++ [OptionName,
string__join_list(" ", VariableValue)]
;
- MMCOptionType = option(split, OptionName),
- OptionsStrings = list__condense(
+ MMCOptionType = option(split, InitialOptions, OptionName),
+ OptionsStrings = list__condense([InitialOptions |
list__map((func(Word) = [OptionName, Word]),
- VariableValue))
+ VariableValue)])
).
:- type mmc_option_type
---> mmc_flags % The options can be passed directly to mmc.
- ; option(split_into_words, option_name :: string)
- % The options need to be passed as an
- % argument of an option to mmc.
+ ; option(split_into_words, initial_options :: list(string),
+ option_name :: string)
+ % The options need to be passed as an
+ % argument of an option to mmc.
+ % The `initial_options' will be passed before
+ % the options generated by the variable.
+ % This is useful for clearing an accumulating option.
.
% The split_into_words type specifies whether there should be
@@ -853,19 +865,21 @@
mmc_option_type(grade_flags) = mmc_flags.
mmc_option_type(mmc_flags) = mmc_flags.
-mmc_option_type(c_flags) = option(not_split, "--cflags").
-mmc_option_type(java_flags) = option(not_split, "--java-flags").
-mmc_option_type(ilasm_flags) = option(not_split, "--ilasm-flags").
-mmc_option_type(mcpp_flags) = option(not_split, "--mcpp-flags").
-mmc_option_type(csharp_flags) = option(not_split, "--csharp-flags").
-mmc_option_type(ml_flags) = option(not_split, "--link-flags").
-mmc_option_type(ml_objs) = option(split, "--link-object").
+mmc_option_type(c_flags) = option(not_split, [], "--cflags").
+mmc_option_type(java_flags) = option(not_split, [], "--java-flags").
+mmc_option_type(ilasm_flags) = option(not_split, [], "--ilasm-flags").
+mmc_option_type(mcpp_flags) = option(not_split, [], "--mcpp-flags").
+mmc_option_type(csharp_flags) = option(not_split, [], "--csharp-flags").
+mmc_option_type(ml_flags) = option(not_split, [], "--link-flags").
+mmc_option_type(ml_objs) = option(split, [], "--link-object").
mmc_option_type(ml_libs) = mmc_flags.
-mmc_option_type(ld_flags) = option(not_split, "--ld-flags").
-mmc_option_type(ld_libflags) = option(not_split, "--ld-libflags").
-mmc_option_type(c2init_args) = option(split, "--init-file").
-mmc_option_type(libraries) = option(split, "--mercury-library").
-mmc_option_type(lib_dirs) = option(split, "--mercury-library-directory").
+mmc_option_type(ld_flags) = option(not_split, [], "--ld-flags").
+mmc_option_type(ld_libflags) = option(not_split, [], "--ld-libflags").
+mmc_option_type(c2init_args) = option(split, [], "--init-file").
+mmc_option_type(libraries) = option(split, [], "--mercury-library").
+mmc_option_type(lib_dirs) = option(split, [], "--mercury-library-directory").
+mmc_option_type(lib_grades) = option(split, ["--no-libgrade"], "--libgrade").
+mmc_option_type(install_prefix) = option(not_split, [], "--install-prefix").
%-----------------------------------------------------------------------------%
Index: compiler/trans_opt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trans_opt.m,v
retrieving revision 1.18
diff -u -u -r1.18 trans_opt.m
--- compiler/trans_opt.m 7 Apr 2002 10:22:51 -0000 1.18
+++ compiler/trans_opt.m 5 Jul 2002 07:21:14 -0000
@@ -160,7 +160,7 @@
maybe_write_string(VeryVerbose, "'... "),
maybe_flush_output(VeryVerbose),
- module_name_to_file_name(Import, ".trans_opt", no, FileName),
+ module_name_to_search_file_name(Import, ".trans_opt", FileName),
prog_io__read_opt_file(FileName, Import,
ModuleError, Messages, Items1),
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.314
diff -u -u -r1.314 user_guide.texi
--- doc/user_guide.texi 12 Jun 2002 14:26:55 -0000 1.314
+++ doc/user_guide.texi 6 Jul 2002 16:47:34 -0000
@@ -838,8 +838,7 @@
The advantages of the @samp{mmc --make} over Mmake are that there
is no @samp{mmake depend} step and the dependencies are more accurate.
-Library installation (@pxref{Libraries}) and parallel builds are not
-yet supported.
+Parallel builds are not yet supported.
The Mmake variables above can be used by @samp{mmc --make} if they
are set in a file called @file{Mercury.options}. The @file{Mercury.options}
Index: scripts/Mmake.vars.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.vars.in,v
retrieving revision 1.74
diff -u -u -r1.74 Mmake.vars.in
--- scripts/Mmake.vars.in 24 Jun 2002 16:15:22 -0000 1.74
+++ scripts/Mmake.vars.in 7 Jul 2002 10:53:55 -0000
@@ -126,6 +126,8 @@
echo LD_LIBFLAGS += '$(ALL_LD_LIBFLAGS)'; \
echo EXTRA_LIBRARIES += '$(EXTRA_LIBRARIES)'; \
echo EXTRA_LIB_DIRS += '$(EXTRA_LIB_DIRS)'; \
+ echo LIBGRADES = '$(ALL_LIBGRADES)'; \
+ echo INSTALL_PREFIX = '$(INSTALL_PREFIX)'; \
}
MC_MAKE_FLAGS =
@@ -185,14 +187,14 @@
MGNUC = mgnuc
ALL_MGNUCFLAGS = $(MGNUCFLAGS) $(EXTRA_MGNUCFLAGS) $(TARGET_MGNUCFLAGS) \
- $(LIB_MGNUCFLAGS) -- $(ALL_CFLAGS)
+ -- $(ALL_CFLAGS)
MGNUCFLAGS =
EXTRA_MGNUCFLAGS =
-LIB_MGNUCFLAGS = $(patsubst %,-I %,$(EXTRA_C_INCL_DIRS))
-ALL_CFLAGS = $(CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CFLAGS)
+ALL_CFLAGS = $(CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CFLAGS) $(LIB_CFLAGS)
CFLAGS =
EXTRA_CFLAGS =
+LIB_CFLAGS = $(patsubst %,-I %,$(EXTRA_C_INCL_DIRS))
#-----------------------------------------------------------------------------#
#
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list