[mercury-users] Problem with linking bigger project (Mercury and C++)

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Dec 16 17:21:49 AEDT 2001

On 15-Dec-2001, Ondrej Bojar <oboj7042 at ss1000.ms.mff.cuni.cz> wrote:
> When trying to link together a bigger project, I get lots of `undefined
> reference' errors for functions/data objects such as:
> MR_ticket_counter_var, MR_trail_ptr_var, MR_ticket_high_water_var,
> MR_untrail_to...

Without seeing the Mmakefile, it's a bit hard to be sure exactly what
is going on, but my guess is that that error message is most likely
because some part of your program was compiled with trailing enabled,
but you didn't enable trailing when linking.  If you use the `--trail'
option with Mmake, make sure that you put it in GRADEFLAGS rather than

> 1. Is the above "ml -o project ..." line correct? Do I miss anything?

In an Mmakefile, rather than hard-coding `ml', you should generally use
`$(ML) $(ALL_GRADEFLAGS) $(ALL_MLFLAGS)'.  This will include the setting
of $(GRADEFLAGS), which is needed if you're building in a non-standard
grade (e.g. with trailing enabled).

> 2. Or can mmake do this for me *by itself*? (If I just specify c_code*.o
> files somewhere.)
> 3. Is there a better scheme to do all the compilations?
> 4. Can anything save me the work of looking up all the necessary module*.o
> files for linking? (The files are of course well known from
> merc_interface.dep...)

Yes to all three.

If you set the `MLOBJS' variable to the c_code*.o files,
then these files will be linked into any Mercury program.

So the Mmakefile for your example could be written like this:

	MLOBJS = cpp_code1.o cpp_code2.o ... cpp_coden.o cpp_main.o
	C2INITFLAGS = --library

	MAIN_TARGET = mercury_interface
	depend: mercury_interface.depend

If you want this to only apply to a particular program,
then you can use `MLOBJS-<program>' rather than `MLOBJS':

	MLOBJS-mercury_interface = \
		cpp_code1.o cpp_code2.o ... cpp_coden.o cpp_main.o
	C2INITFLAGS-mercury_interface = --library

	MAIN_TARGET = mercury_interface
	depend: mercury_interface.depend

These both have the minor drawback that the executable is named
`mercury_interface' rather than `project'.  The simplest fix
for that is to just add the following:

	project: mercury_interface
		cp mercury_interface project

Another way of doing it is to have an empty top-level module

	:- module project.
	:- import_module mercury_interface.

in the file project.m and then use

	MLOBJS-project = \
		cpp_code1.o cpp_code2.o ... cpp_coden.o cpp_main.o
	C2INITFLAGS-project = --library

	MAIN_TARGET = mercury_interface
	depend: mercury_interface.depend

Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list