[m-dev.] For review: Simplified installation of user libraries

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Sep 29 22:25:57 AEST 1999


On 29-Sep-1999, Warwick Harvey <wharvey at cs.monash.edu.au> wrote:
> I guess for Fergus to review.  Ralph might want to have a look at it too.
> 
> Should `.opt' files always be built and installed regardless of the 
> intermodule optimisation level settings?

The Mercury User's Guide says the following:

 | If the people using
 | the library are going to use intermodule optimization, you will also
 | need the intermodule optimization interfaces.  That's why the
 | `libmypackage' target builds `$(mypackage.opts)'.

However, given the way things work at the moment, having the library
build/install targets always build/install the `.opt' files is actually
a bad idea, because just building the `.opt' files is not enough.
Code which is generated using information in `.opt' files
won't work unless the modules with the `.opt' files were also compiled
with intermodule optimization.  The problem is that the `.opt' file may
contain declarations of procedures local to a module, and code generated
using the `.opt' file may contain references to those procedures,
but if the module wasn't compiled with intermodule optimization,
then the compiler may define these procedures as `static' in the generated
C code, so those references to them from other modules would result in
link errors.

Another point is that library developers may want to be able to install
a new version of a shared library without recompiling the applications
that use it; that won't work if the `.opt' files have been installed
and any of the applications that use it were compiled with intermodule
optimization.  So there should be some way of disabling the
installation of `.opt' files.

So I think it would be best if the `.opt' files were not built and installed
unless the library was compiled with intermodule optimization enabled.
However the Mercury User's Guide should advise library developers to compile
their libraries with intermodule optimization enabled.

> What about `.trans_opt' files?

Likewise.

> Estimated hours taken: 18
> 
> Added built-in mmake support for installing user libraries.
...
> cvs server: Diffing compiler
> Index: compiler/modules.m
...
> +	io__write_strings(DepStream, [
> +		".PHONY : ", LibInstallIntsTargetName, "\n",
> +		LibInstallIntsTargetName, " : $(", MakeVarName, ".ints) $(",
> +			MakeVarName, ".int3s) ", MaybeOptsVar,
> +			MaybeTransOptsVar, "install_lib_dirs\n",
> +		"\tfor file in $(", MakeVarName, ".ints) $(", MakeVarName,
> +			".int3s) ", MaybeOptsVar, MaybeTransOptsVar,
> +			"; do \\\n",
> +		"\t\ttarget=$(INSTALL_INT_DIR)/`basename $$file`; \\\n",
> +		"\t\tif cmp -s $$file $$target; then \\\n",
> +		"\t\t\techo \"$$target unchanged\"; \\\n",
> +		"\t\telse \\\n",
> +		"\t\t\techo \"installing $$target\"; \\\n",
> +		"\t\t\tcp $$file $$target; \\\n",
> +		"\t\tfi; \\\n",
> +		"\tdone\n",
> +		"\t# The following is needed to support the `--use-subdirs'",
> +			" option\n",
> +		"\t# We try using `ln -s', but if that fails, then we just",
> +			" use `cp'.\n",
> +		"\tfor ext in int int2 int3 opt trans_opt; do \\\n",
> +		"\t\tdir=$${ext}s; \\\n",
> +		"\t\trm -f $(INSTALL_INT_DIR)/Mercury/$$dir; \\\n",
> +		"\t\tln -s .. $(INSTALL_INT_DIR)/Mercury/$$dir || { \\\n",
> +		"\t\t\tmkdir $(INSTALL_INT_DIR)/Mercury/$$dir && \\\n",
> +		"\t\t\tcp $(INSTALL_INT_DIR)/*.$$ext \\\n",
> +		"\t\t\t\t$(INSTALL_INT_DIR)/Mercury/$$dir; \\\n",
> +		"\t\t} || exit 1; \\\n",
> +		"\tdone\n\n"

Hmm, it's a bit hard to read and maintain such a long section of code
in that form.  I think it would be clearer to write most of that as a
single string literal:

	InstallIntsRuleBody = "\\
		for file in $$files; do \\
			target=$(INSTALL_INT_DIR)/`basename $$file`; \\
			if cmp -s $$file $$target; then \\
				echo \"$$target unchanged\"; \\
			else \\
				echo \"installing $$target\"; \\
				cp $$file $$target; \\
			fi; \\
		done
		# The following is needed to support the `--use-subdirs' option
		# We try using `ln -s', but if that fails, then we just use `cp'.
		for ext in int int2 int3 opt trans_opt; do \\
			dir=$${ext}s; \\
			rm -f $(INSTALL_INT_DIR)/Mercury/$$dir; \\
			ln -s .. $(INSTALL_INT_DIR)/Mercury/$$dir || { \\
				mkdir $(INSTALL_INT_DIR)/Mercury/$$dir && \\
				cp $(INSTALL_INT_DIR)/*.$$ext \\
					$(INSTALL_INT_DIR)/Mercury/$$dir; \\
			} || exit 1; \\
		done \\
	\n",

	io__write_strings(DepStream, [
		".PHONY : ", LibInstallIntsTargetName, "\n",
		LibInstallIntsTargetName, " : $(", MakeVarName, ".ints) $(",
			MakeVarName, ".int3s) ", MaybeOptsVar,
			MaybeTransOptsVar, "install_lib_dirs\n",
		"\tfiles=""$(", MakeVarName, ".ints) $(", MakeVarName,
			".int3s) ", MaybeOptsVar, MaybeTransOptsVar,
			""" \\\n",
		InstallIntsRuleBody
  	]),

> Index: doc/user_guide.texi
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
> retrieving revision 1.184
> diff -u -r1.184 user_guide.texi
> --- user_guide.texi	1999/08/18 06:26:06	1.184
> +++ user_guide.texi	1999/09/29 09:56:59
> @@ -427,6 +427,12 @@
>  (for platforms that support it), and the necessary interface files.
>  For more information, see @ref{Libraries}.
>  
> + at item lib at var{main-module}.install
> +Builds and installs a library whose top-level module is @var{main-module}.
> +This will build and install a static object library, a shared object library
> +(for platforms that support it), and the necessary interface files.
> +For more information, see @ref{Supporting multiple grades and architectures}.

I think that documentation is misleading, because it suggests that it only
installs the libraries for one grade, but (if I understand things correctly)
actually it will installed them for multiple grades by default.
Therefore I suggest replacing that with the following
(here "|" denotes the changed lines):

    @item lib at var{main-module}.install
    Builds and installs a library whose top-level module is @var{main-module}.
|   This target will build and install a static object library and
|   (for platforms that support it) a shared object library,
|   for the default grade and also for the additional grades specified
|   in the LIBGRADES variable.  It will also build and install the
    necessary interface files.
    For more information, see @ref{Supporting multiple grades and architectures}.

> +Note that at this stage is not possible to set the installation prefix
> +on a library-by-library basis.

I suggest s/at this stage/currently/

> +lib%.install_grades:
> +	rm -rf tmp_dir && \
> +	mkdir tmp_dir && \
> +	{ mv -f *.c *.o *.pic_o *.a *.so tmp_dir || true; } && \
> +	for grade in x $(ALL_LIBGRADES); do \
> +		if [ "$$grade" != "x" ]; then \
> +			$(MMAKE) GRADE=$$grade lib$*.install_library || \
> +				exit 1; \
> +			rm -rf *.c *.o *.pic_o *.a *.so; \
> +		fi; \
> +	done && \
> +	{ mv tmp_dir/* . ; rmdir tmp_dir ; true }
> +
> +lib%.install_split_grades:
> +	rm -rf tmp_dir && \
> +	mkdir tmp_dir && \
> +	{ mv -f *.dir *.c *.o *.pic_o *.a *.so tmp_dir || true; } && \
> +	for grade in x $(ALL_LIBGRADES); do \
> +		if [ "$$grade" != "x" ]; then \
> +			$(MMAKE) GRADE=$$grade lib$*.install_split_library || \
> +				exit 1; \
> +			rm -rf *.dir *.c *.o *.pic_o *.a *.so; \
> +		fi; \
> +	done && \
> +	{ mv tmp_dir/* . ; rmdir tmp_dir ; true }

Those rules won't work correctly if `--use-subdirs' is enabled.
I think the following will fix it,

	s/*.dir/$(dirs_subdir)*.dir/g
	s/*.c/$(cs_subdir)*.c/g
	s/*.o/$(os_subdir)*.o/g
	s/*.pic_o/$(os_subdir)*.pic_o/g

but I haven't tested that.

There are a also other flaws with those rules, in particular
the danger of moving or removing *.c, problems if run concurrently,
and leaving the directory in a nasty state if the install fails.
Fixes for those are not as easy.  But I suppose those problems
are tolerable for now.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list