[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