[m-rev.] for review: improve `_init.c' file creation
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Nov 27 18:57:40 AEDT 2001
Estimated hours taken: 2
Branches: main
Improvements for the code which creates the `_init.o' files.
compiler/modules.m:
compiler/mercury_compile.m:
Update the `_init.c' file if the c2init command
line has changed since the last time it was run,
for example if the user has added C2INITFLAGS=--trace.
compiler/mercury_compile.m:
Separate out the code to create the `_init.o' file into
a new predicate.
Pass the grade to c2init.
Use the `--init-c-file' c2init option rather than `-o'.
Index: mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.226
diff -u -u -r1.226 mercury_compile.m
--- mercury_compile.m 26 Nov 2001 10:57:31 -0000 1.226
+++ mercury_compile.m 27 Nov 2001 07:54:54 -0000
@@ -3799,9 +3799,6 @@
{ file_name_to_module_name(OutputFileName, ModuleName) },
globals__io_lookup_string_option(object_file_extension, Obj),
- { string__append("_init", Obj, InitObj) },
- module_name_to_file_name(ModuleName, "_init.c", yes, InitCFileName),
- module_name_to_file_name(ModuleName, InitObj, yes, InitObjFileName),
globals__io_get_target(Target),
globals__io_lookup_bool_option(split_c_files, SplitFiles),
@@ -3833,46 +3830,21 @@
( { MakeLibCmdOK = no } ->
report_error("creation of object file library failed.")
;
- % create the initialization C file
- maybe_write_string(Verbose, "% Creating initialization file...\n"),
+ globals__io_get_globals(Globals),
+ { compute_grade(Globals, Grade) },
globals__io_get_trace_level(TraceLevel),
{ trace_level_is_none(TraceLevel) = no ->
TraceOpt = "--trace "
;
TraceOpt = ""
},
-
- globals__io_lookup_accumulating_option(init_file_directories,
- InitFileDirsList),
- { join_string_list(InitFileDirsList, "-I ", "",
- " ", InitFileDirs) },
-
- globals__io_lookup_accumulating_option(init_files,
- InitFileNamesList),
- { join_string_list(InitFileNamesList, "", "",
- " ", InitFileNames) },
-
- join_module_list(Modules, ".c", [], CFileNames),
- { MkInitCmd = string__append_list(
- ["c2init ", TraceOpt, " -o ", InitCFileName, " ",
- InitFileDirs, " ", InitFileNames, " " | CFileNames]) },
- invoke_shell_command(MkInitCmd, MkInitOK),
- maybe_report_stats(Stats),
- ( { MkInitOK = no } ->
- report_error("creation of init file failed.")
+ mercury_compile__make_init_o_file(Grade, TraceOpt,
+ ModuleName, Modules, InitObjFileName, InitOK),
+ (
+ { InitOK = no }
;
- % compile it
- maybe_write_string(Verbose,
- "% Compiling initialization file...\n"),
- mercury_compile__single_c_to_obj(InitCFileName, InitObjFileName,
- CompileOK),
- maybe_report_stats(Stats),
- ( { CompileOK = no } ->
- report_error("compilation of init file failed.")
- ;
+ { InitOK = yes },
maybe_write_string(Verbose, "% Linking...\n"),
- globals__io_get_globals(Globals),
- { compute_grade(Globals, Grade) },
globals__io_lookup_bool_option(target_debug, Target_Debug),
{ Target_Debug = yes ->
Target_Debug_Opt = "--no-strip "
@@ -3910,8 +3882,146 @@
;
[]
)
- )
)
+ ).
+
+:- pred mercury_compile__make_init_o_file(string, string, module_name,
+ list(string), file_name, bool, io__state, io__state).
+:- mode mercury_compile__make_init_o_file(in, in, in,
+ in, out, out, di, uo) is det.
+
+mercury_compile__make_init_o_file(Grade, TraceOpt,
+ ModuleName, Modules, InitObjFileName, InitOK) -->
+ globals__io_lookup_bool_option(verbose, Verbose),
+ globals__io_lookup_bool_option(statistics, Stats),
+
+ globals__io_lookup_string_option(object_file_extension, Obj),
+ { string__append("_init", Obj, InitObj) },
+ module_name_to_file_name(ModuleName, "_init.c", yes, InitCFileName),
+ module_name_to_file_name(ModuleName, InitObj, yes, InitObjFileName),
+
+ globals__io_lookup_accumulating_option(init_file_directories,
+ InitFileDirsList),
+ { join_string_list(InitFileDirsList, "-I ", "", " ", InitFileDirs) },
+
+ globals__io_lookup_accumulating_option(init_files, InitFileNamesList),
+ { join_string_list(InitFileNamesList, "", "", " ", InitFileNames) },
+
+ join_module_list(Modules, ".c", [], CFileNames),
+
+ { MkInitCmd = string__append_list(
+ ["c2init --grade ", Grade, " ", TraceOpt,
+ " --init-c-file ", InitCFileName, " ", InitFileDirs, " ",
+ InitFileNames, " " | CFileNames]) },
+
+ %
+ % If the command to create the `_init.c' file hasn't changed
+ % and the `_init.c' and `_init.o' files are present, don't
+ % recreate them.
+ %
+ { CommandFileName = InitCFileName ++ ".cmd" },
+ io__open_input(CommandFileName, CommandFileRes),
+ (
+ { CommandFileRes = ok(CommandFileStream) },
+ % XXX Why does `io__read_file_as_string' return a separate
+ % status and result, rather than an `io__res(string)'?
+ io__read_file_as_string(CommandFileStream,
+ OldCommandRes, OldCommand),
+ io__close_input(CommandFileStream),
+
+ ( { OldCommandRes = ok, OldCommand = MkInitCmd } ->
+ %
+ % Check that the C file was built after the
+ % command file, and the object file was built
+ % after the C file.
+ %
+ io__file_modification_time(CommandFileName,
+ CommandFileTimeRes),
+ io__file_modification_time(InitCFileName,
+ InitCTimeRes),
+ io__file_modification_time(InitObjFileName,
+ InitObjTimeRes),
+ {
+ InitCTimeRes = ok(InitCTime),
+ InitObjTimeRes = ok(InitObjTime),
+ CommandFileTimeRes = ok(CommandFileTime),
+ compare(C_Command_TimeCompare,
+ InitCTime, CommandFileTime),
+ ( C_Command_TimeCompare = (=)
+ ; C_Command_TimeCompare = (>)
+ ),
+ compare(Obj_C_TimeCompare,
+ InitObjTime, InitCTime),
+ ( Obj_C_TimeCompare = (=)
+ ; Obj_C_TimeCompare = (>)
+ )
+ ->
+ RecreateInitFile = no
+ ;
+ RecreateInitFile = yes
+ }
+ ;
+ { RecreateInitFile = yes }
+ )
+ ;
+ { CommandFileRes = error(_) },
+ { RecreateInitFile = yes }
+ ),
+
+ (
+ { RecreateInitFile = yes },
+ %
+ % Record the command used to make the `_init.c' file.
+ %
+ io__open_output(CommandFileName, CommandFileOutputRes),
+ (
+ { CommandFileOutputRes = ok(CommandFileOutputStream) },
+ io__write_string(CommandFileOutputStream, MkInitCmd),
+ io__close_output(CommandFileOutputStream),
+
+ %
+ % Create the initialization C file
+ %
+ invoke_shell_command(MkInitCmd, MkInitOK),
+ maybe_report_stats(Stats),
+ (
+ { MkInitOK = no },
+ { InitOK = no },
+ report_error("creation of init file failed.")
+ ;
+ { MkInitOK = yes },
+ maybe_write_string(Verbose,
+ "% Compiling initialization file...\n"),
+
+ %
+ % Compile it.
+ %
+ mercury_compile__single_c_to_obj(InitCFileName,
+ InitObjFileName, InitOK),
+ maybe_report_stats(Stats),
+ (
+ { InitOK = yes }
+ ;
+ { InitOK = no },
+ report_error(
+ "compilation of init file failed.")
+ )
+ )
+ ;
+ { CommandFileOutputRes = error(CommandFileError) },
+ { io__error_message(CommandFileError,
+ CommandFileMsg) },
+ report_error(
+ string__append_list(
+ ["can't open file `", CommandFileName,
+ "' for output: ", CommandFileMsg])),
+ { InitOK = no }
+ )
+ ;
+ { RecreateInitFile = no },
+ maybe_write_string(Verbose,
+ "% Initialization file is up to date.\n"),
+ { InitOK = yes }
).
% join_string_list(Strings, Prefix, Suffix, Serarator, Result)
Index: modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.208
diff -u -u -r1.208 modules.m
--- modules.m 24 Nov 2001 17:52:15 -0000 1.208
+++ modules.m 27 Nov 2001 07:45:51 -0000
@@ -3664,14 +3664,41 @@
list__foldl(append_to_init_list(DepStream, InitFileName), Modules),
io__write_string(DepStream, "\n"),
+ %
+ % Define a variable to hold the c2init command line.
+ %
+ { C2InitCmdVarName = "C2INIT_CMD-" ++ MakeVarName },
io__write_strings(DepStream, [
- InitCFileName, " : ", DepFileName, " ", DvFileName, " ",
- All_C2InitArgsDepString, "\n",
- "\t$(C2INIT) $(ALL_GRADEFLAGS) $(ALL_C2INITFLAGS) ",
+ C2InitCmdVarName, " = ",
+ "$(C2INIT) $(ALL_GRADEFLAGS) $(ALL_C2INITFLAGS) ",
"--init-c-file ", InitCFileName,
" $(", MakeVarName, ".init_cs) $(ALL_C2INITARGS)\n\n"
]),
+ %
+ % Update `module_init.c.cmd' if the c2init command line
+ % has changed since the last time it was built.
+ % The `FORCE-module.c.cmd' dependency forces the commands for
+ % the `module_init.c.cmd' rule to be run every time the rule
+ % is considered.
+ %
+ { C2InitCmdFileName = InitCFileName ++ ".cmd" },
+ { TmpC2InitCmdFileName = C2InitCmdFileName ++ ".tmp" },
+ { ForceC2InitCmdTarget = "FORCE-" ++ C2InitCmdFileName },
+ io__write_strings(DepStream, [
+ ForceC2InitCmdTarget, " :\n\n",
+ C2InitCmdFileName, " : ", ForceC2InitCmdTarget, "\n",
+ "\t at echo $(", C2InitCmdVarName, ") > ",
+ TmpC2InitCmdFileName, "\n",
+ "\t at mercury_update_interface ", C2InitCmdFileName, "\n\n"
+ ]),
+
+ io__write_strings(DepStream, [
+ InitCFileName, " : ", DepFileName, " ", DvFileName, " ",
+ C2InitCmdFileName, " ", All_C2InitArgsDepString, "\n",
+ "\t$(", C2InitCmdVarName, ")\n\n"
+ ]),
+
module_name_to_lib_file_name("lib", ModuleName, ".install_ints", no,
LibInstallIntsTargetName),
{ InstallIntsRuleBody =
@@ -3802,7 +3829,8 @@
".PHONY : ", CleanTargetName, "\n",
CleanTargetName, " :\n",
"\t-rm -rf $(", MakeVarName, ".dirs)\n",
- "\t-rm -f $(", MakeVarName, ".cs) ", InitCFileName, "\n",
+ "\t-rm -f $(", MakeVarName, ".cs) ", InitCFileName, " ",
+ C2InitCmdFileName, "\n",
"\t-rm -f $(", MakeVarName, ".all_ss) ", InitAsmFileName, "\n",
"\t-rm -f $(", MakeVarName, ".all_pic_ss) ",
InitAsmFileName, "\n",
--------------------------------------------------------------------------
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