[m-rev.] diff: option to query compiler about linker flags
Julien Fischer
juliensf at csse.unimelb.edu.au
Mon Jan 19 16:22:12 AEDT 2009
Note: we probably need to do a little more work for this to work
in .par and .debug grades (and probably on Mac OS X). I will look
into those things separately though. Once everythings is more less
stable I will update the standalone interface section of the user's
guide.
----
Add a new command line option that causes the compiler to print out the
set of flags that it passes to the linker in order to link against a
selected set of Mercury libraries (the standard libraries plus any others
specified via the --ml option) in the current grade.
This removes the need for using the ml script with standalone interfaces.
(Which is useful on those systems that don't have a proper shell and can't
use that script!)
compiler/compiler_target_code.m:
Add a predicate that prints out the above information.
Refactor code in order to to avoid duplication between the new
functionality and the existing code for invoking the linker.
compiler/mercury_compile.m:
compiler/options.m:
Add the new option.
doc/user_guide.texi:
Add an entry for the new option.
samples/c_interface/standalone_c/Makefile:
Query the compiler directly about what flags to pass to the linker
rather than using the ml script.
Query the compiler about what flags to pass to the C compiler as
well. (This was implemented a while ago, but this example was
never updated.)
Extend this example to optionally work with shared libraries.
Julien.
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.134
diff -u -r1.134 compile_target_code.m
--- compiler/compile_target_code.m 11 Dec 2008 15:12:16 -0000 1.134
+++ compiler/compile_target_code.m 16 Jan 2009 07:30:56 -0000
@@ -188,7 +188,10 @@
is det.
%-----------------------------------------------------------------------------%
-
+%
+% Stuff used for standalone interfaces
+%
+
% make_standalone_interface(Basename, !IO):
%
% Create a standalone interface in the current directory.
@@ -200,6 +203,14 @@
%
:- pred output_c_compiler_flags(io.output_stream::in, io::di, io::uo) is det.
+ % Output the list of flags required to link against the selected set
+ % of Mercury libraries (the standard libraries, plus any other specified
+ % via the --ml option) in the current grade.
+ % This predicate is used to implement the `--output-library-link-flags'
+ % option.
+ %
+:- pred output_library_link_flags(io.output_stream::in, io::di, io::uo) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -1710,16 +1721,7 @@
),
% Find the Mercury standard libraries.
- globals.io_lookup_maybe_string_option(
- mercury_standard_library_directory, MaybeStdLibDir, !IO),
- (
- MaybeStdLibDir = yes(StdLibDir),
- get_mercury_std_libs(LinkTargetType, StdLibDir, MercuryStdLibs,
- !IO)
- ;
- MaybeStdLibDir = no,
- MercuryStdLibs = ""
- ),
+ get_mercury_std_libs(LinkTargetType, MercuryStdLibs, !IO),
% Find which system libraries are needed.
get_system_libs(LinkTargetType, SystemLibs, !IO),
@@ -1734,34 +1736,12 @@
" ", LinkLibraryDirectories),
% Set up the runtime library path.
+ get_runtime_library_path_opts(LinkTargetType, RpathFlagOpt, RpathSepOpt,
+ RpathOpts, !IO),
+
+ % Set up the install name for shared libraries.
globals.io_lookup_bool_option(shlib_linker_use_install_name,
UseInstallName, !IO),
- shared_libraries_supported(SharedLibsSupported, !IO),
- (
- UseInstallName = no,
- SharedLibsSupported = yes,
- ( Linkage = "shared"
- ; LinkTargetType = shared_library
- )
- ->
- globals.io_lookup_accumulating_option(
- runtime_link_library_directories, RpathDirs0, !IO),
- RpathDirs = list.map(quote_arg, RpathDirs0),
- (
- RpathDirs = [],
- RpathOpts = ""
- ;
- RpathDirs = [_ | _],
- globals.io_lookup_string_option(RpathSepOpt, RpathSep, !IO),
- globals.io_lookup_string_option(RpathFlagOpt, RpathFlag, !IO),
- RpathOpts0 = string.join_list(RpathSep, RpathDirs),
- RpathOpts = RpathFlag ++ RpathOpts0
- )
- ;
- RpathOpts = ""
- ),
-
- % Set up the install name for shared libraries.
(
UseInstallName = yes,
LinkTargetType = shared_library
@@ -1787,27 +1767,11 @@
globals.io_lookup_string_option(TraceFlagsOpt, TraceOpts, !IO)
),
- % Pass either `-llib' or `PREFIX/lib/GRADE/liblib.a',
- % depending on whether we are linking with static or shared
- % Mercury libraries.
-
- globals.io_lookup_accumulating_option(
- mercury_library_directories, MercuryLibDirs0, !IO),
- globals.io_get_globals(Globals, !IO),
- grade_directory_component(Globals, GradeDir),
- MercuryLibDirs = list.map(
- (func(LibDir) = LibDir/"lib"/GradeDir),
- MercuryLibDirs0),
- globals.io_lookup_accumulating_option(link_libraries,
- LinkLibrariesList0, !IO),
- list.map_foldl2(process_link_library(MercuryLibDirs),
- LinkLibrariesList0, LinkLibrariesList, yes,
- LibrariesSucceeded, !IO),
-
+ get_link_libraries(MaybeLinkLibraries, !IO),
globals.io_lookup_string_option(linker_opt_separator,
LinkOptSep, !IO),
(
- LibrariesSucceeded = yes,
+ MaybeLinkLibraries = yes(LinkLibrariesList),
join_quoted_string_list(LinkLibrariesList, "", "", " ",
LinkLibraries),
@@ -1884,147 +1848,184 @@
MaybeDeleteTmpArchive = no
)
;
- LibrariesSucceeded = no,
+ MaybeLinkLibraries = no,
LinkSucceeded = no
).
-
+
% Find the standard Mercury libraries, and the system
% libraries needed by them.
+ % Return the empty string if --mercury-standard-library-directory
+ % is not set.
%
-:- pred get_mercury_std_libs(linked_target_type::in, dir_name::in, string::out,
+:- pred get_mercury_std_libs(linked_target_type::in, string::out,
io::di, io::uo) is det.
-get_mercury_std_libs(TargetType, StdLibDir, StdLibs, !IO) :-
- globals.io_get_gc_method(GCMethod, !IO),
- (
- ( TargetType = executable
- ; TargetType = static_library
- ; TargetType = shared_library
- ),
- globals.io_lookup_string_option(library_extension, LibExt, !IO)
- ;
- TargetType = java_archive,
- unexpected(this_file, "get_mercury_std_libs: java_archive")
- ;
- TargetType = erlang_archive,
- unexpected(this_file, "get_mercury_std_libs: erlang_archive")
- ),
- globals.io_get_globals(Globals, !IO),
- grade_directory_component(Globals, GradeDir),
-
- % GC libraries.
+get_mercury_std_libs(TargetType, StdLibs, !IO) :-
+ globals.io_lookup_maybe_string_option(
+ mercury_standard_library_directory, MaybeStdlibDir, !IO),
(
- GCMethod = gc_automatic,
- StaticGCLibs = "",
- SharedGCLibs = ""
- ;
- GCMethod = gc_none,
- StaticGCLibs = "",
- SharedGCLibs = ""
- ;
+ MaybeStdlibDir = yes(StdLibDir),
+ globals.io_get_gc_method(GCMethod, !IO),
(
- GCMethod = gc_boehm,
- GCGrade0 = "gc"
+ ( TargetType = executable
+ ; TargetType = static_library
+ ; TargetType = shared_library
+ ),
+ globals.io_lookup_string_option(library_extension, LibExt, !IO)
+ ;
+ TargetType = java_archive,
+ unexpected(this_file, "get_mercury_std_libs: java_archive")
;
- GCMethod = gc_boehm_debug,
- GCGrade0 = "gc_debug"
+ TargetType = erlang_archive,
+ unexpected(this_file, "get_mercury_std_libs: erlang_archive")
),
- globals.io_lookup_bool_option(profile_time, ProfTime, !IO),
- globals.io_lookup_bool_option(profile_deep, ProfDeep, !IO),
+ globals.io_get_globals(Globals, !IO),
+ grade_directory_component(Globals, GradeDir),
+
+ % GC libraries.
(
- ( ProfTime = yes
- ; ProfDeep = yes
- )
- ->
- GCGrade1 = GCGrade0 ++ "_prof"
+ GCMethod = gc_automatic,
+ StaticGCLibs = "",
+ SharedGCLibs = ""
+ ;
+ GCMethod = gc_none,
+ StaticGCLibs = "",
+ SharedGCLibs = ""
;
- GCGrade1 = GCGrade0
+ (
+ GCMethod = gc_boehm,
+ GCGrade0 = "gc"
+ ;
+ GCMethod = gc_boehm_debug,
+ GCGrade0 = "gc_debug"
+ ),
+ globals.io_lookup_bool_option(profile_time, ProfTime, !IO),
+ globals.io_lookup_bool_option(profile_deep, ProfDeep, !IO),
+ (
+ ( ProfTime = yes
+ ; ProfDeep = yes
+ )
+ ->
+ GCGrade1 = GCGrade0 ++ "_prof"
+ ;
+ GCGrade1 = GCGrade0
+ ),
+ globals.io_lookup_bool_option(parallel, Parallel, !IO),
+ (
+ Parallel = yes,
+ GCGrade = "par_" ++ GCGrade1
+ ;
+ Parallel = no,
+ GCGrade = GCGrade1
+ ),
+ make_link_lib(TargetType, GCGrade, SharedGCLibs, !IO),
+ StaticGCLibs = quote_arg(StdLibDir/"lib"/
+ ("lib" ++ GCGrade ++ LibExt))
+ ;
+ GCMethod = gc_mps,
+ make_link_lib(TargetType, "mps", SharedGCLibs, !IO),
+ StaticGCLibs = quote_arg(StdLibDir/"lib"/
+ ("libmps" ++ LibExt) )
+ ;
+ GCMethod = gc_accurate,
+ StaticGCLibs = "",
+ SharedGCLibs = ""
+ ),
+
+ % Trace libraries.
+ globals.io_get_trace_level(TraceLevel, !IO),
+ ( given_trace_level_is_none(TraceLevel) = yes ->
+ StaticTraceLibs = "",
+ SharedTraceLibs = ""
+ ;
+ StaticTraceLibs =
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_trace" ++ LibExt)) ++
+ " " ++
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_eventspec" ++ LibExt)) ++
+ " " ++
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_browser" ++ LibExt)) ++
+ " " ++
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_mdbcomp" ++ LibExt)),
+ make_link_lib(TargetType, "mer_trace", TraceLib, !IO),
+ make_link_lib(TargetType, "mer_eventspec", EventSpecLib, !IO),
+ make_link_lib(TargetType, "mer_browser", BrowserLib, !IO),
+ make_link_lib(TargetType, "mer_mdbcomp", MdbCompLib, !IO),
+ SharedTraceLibs = string.join_list(" ",
+ [TraceLib, EventSpecLib, BrowserLib, MdbCompLib])
),
- globals.io_lookup_bool_option(parallel, Parallel, !IO),
+
+ % Source-to-source debugging libraries.
+ globals.io_lookup_bool_option(source_to_source_debug, SourceDebug, !IO),
(
- Parallel = yes,
- GCGrade = "par_" ++ GCGrade1
- ;
- Parallel = no,
- GCGrade = GCGrade1
+ SourceDebug = yes,
+ StaticSourceDebugLibs =
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_ssdb" ++ LibExt)),
+ make_link_lib(TargetType, "mer_mdbcomp", SharedSourceDebugLibs, !IO)
+ ;
+ SourceDebug = no,
+ StaticSourceDebugLibs = "",
+ SharedSourceDebugLibs = ""
),
- make_link_lib(TargetType, GCGrade, SharedGCLibs, !IO),
- StaticGCLibs = quote_arg(StdLibDir/"lib"/
- ("lib" ++ GCGrade ++ LibExt))
- ;
- GCMethod = gc_mps,
- make_link_lib(TargetType, "mps", SharedGCLibs, !IO),
- StaticGCLibs = quote_arg(StdLibDir/"lib"/
- ("libmps" ++ LibExt) )
- ;
- GCMethod = gc_accurate,
- StaticGCLibs = "",
- SharedGCLibs = ""
- ),
- % Trace libraries.
- globals.io_get_trace_level(TraceLevel, !IO),
- ( given_trace_level_is_none(TraceLevel) = yes ->
- StaticTraceLibs = "",
- SharedTraceLibs = ""
+ globals.io_lookup_string_option(mercury_linkage, MercuryLinkage, !IO),
+ ( MercuryLinkage = "static" ->
+ StdLibs = string.join_list(" ", [
+ StaticTraceLibs,
+ StaticSourceDebugLibs,
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_std" ++ LibExt)),
+ quote_arg(StdLibDir/"lib"/GradeDir/
+ ("libmer_rt" ++ LibExt)),
+ StaticGCLibs
+ ])
+ ; MercuryLinkage = "shared" ->
+ make_link_lib(TargetType, "mer_std", StdLib, !IO),
+ make_link_lib(TargetType, "mer_rt", RuntimeLib, !IO),
+ StdLibs = string.join_list(" ", [
+ SharedTraceLibs,
+ SharedSourceDebugLibs,
+ StdLib,
+ RuntimeLib,
+ SharedGCLibs
+ ])
+ ;
+ unexpected(this_file, "unknown linkage " ++ MercuryLinkage)
+ )
;
- StaticTraceLibs =
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_trace" ++ LibExt)) ++
- " " ++
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_eventspec" ++ LibExt)) ++
- " " ++
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_browser" ++ LibExt)) ++
- " " ++
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_mdbcomp" ++ LibExt)),
- make_link_lib(TargetType, "mer_trace", TraceLib, !IO),
- make_link_lib(TargetType, "mer_eventspec", EventSpecLib, !IO),
- make_link_lib(TargetType, "mer_browser", BrowserLib, !IO),
- make_link_lib(TargetType, "mer_mdbcomp", MdbCompLib, !IO),
- SharedTraceLibs = string.join_list(" ",
- [TraceLib, EventSpecLib, BrowserLib, MdbCompLib])
- ),
+ MaybeStdlibDir = no,
+ StdLibs = ""
+ ).
+
+ % Pass either `-llib' or `PREFIX/lib/GRADE/liblib.a',
+ % depending on whether we are linking with static or shared
+ % Mercury libraries.
+ %
+:- pred get_link_libraries(maybe(list(string))::out, io::di, io::uo) is det.
- % Source-to-source debugging libraries.
- globals.io_lookup_bool_option(source_to_source_debug, SourceDebug, !IO),
+get_link_libraries(MaybeLinkLibraries, !IO) :-
+ globals.io_lookup_accumulating_option(
+ mercury_library_directories, MercuryLibDirs0, !IO),
+ globals.io_get_globals(Globals, !IO),
+ grade_directory_component(Globals, GradeDir),
+ MercuryLibDirs = list.map(
+ (func(LibDir) = LibDir/"lib"/GradeDir),
+ MercuryLibDirs0),
+ globals.io_lookup_accumulating_option(link_libraries,
+ LinkLibrariesList0, !IO),
+ list.map_foldl2(process_link_library(MercuryLibDirs),
+ LinkLibrariesList0, LinkLibrariesList, yes,
+ LibrariesSucceeded, !IO),
(
- SourceDebug = yes,
- StaticSourceDebugLibs =
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_ssdb" ++ LibExt)),
- make_link_lib(TargetType, "mer_mdbcomp", SharedSourceDebugLibs, !IO)
- ;
- SourceDebug = no,
- StaticSourceDebugLibs = "",
- SharedSourceDebugLibs = ""
- ),
-
- globals.io_lookup_string_option(mercury_linkage, MercuryLinkage, !IO),
- ( MercuryLinkage = "static" ->
- StdLibs = string.join_list(" ", [
- StaticTraceLibs,
- StaticSourceDebugLibs,
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_std" ++ LibExt)),
- quote_arg(StdLibDir/"lib"/GradeDir/
- ("libmer_rt" ++ LibExt)),
- StaticGCLibs
- ])
- ; MercuryLinkage = "shared" ->
- make_link_lib(TargetType, "mer_std", StdLib, !IO),
- make_link_lib(TargetType, "mer_rt", RuntimeLib, !IO),
- StdLibs = string.join_list(" ", [
- SharedTraceLibs,
- SharedSourceDebugLibs,
- StdLib,
- RuntimeLib,
- SharedGCLibs
- ])
+ LibrariesSucceeded = yes,
+ MaybeLinkLibraries = yes(LinkLibrariesList)
;
- unexpected(this_file, "unknown linkage " ++ MercuryLinkage)
+ LibrariesSucceeded = no,
+ MaybeLinkLibraries = no
).
:- pred make_link_lib(linked_target_type::in, string::in, string::out,
@@ -2055,6 +2056,40 @@
unexpected(this_file, "make_link_lib: static_library")
).
+:- pred get_runtime_library_path_opts(linked_target_type::in,
+ option::in(bound(shlib_linker_rpath_flag ; linker_rpath_flag)),
+ option::in(bound(shlib_linker_rpath_separator ; linker_rpath_separator)),
+ string::out, io::di, io::uo) is det.
+
+get_runtime_library_path_opts(LinkTargetType, RpathFlagOpt, RpathSepOpt, RpathOpts, !IO) :-
+ globals.io_lookup_bool_option(shlib_linker_use_install_name,
+ UseInstallName, !IO),
+ shared_libraries_supported(SharedLibsSupported, !IO),
+ globals.io_lookup_string_option(linkage, Linkage, !IO),
+ (
+ UseInstallName = no,
+ SharedLibsSupported = yes,
+ ( Linkage = "shared"
+ ; LinkTargetType = shared_library
+ )
+ ->
+ globals.io_lookup_accumulating_option(
+ runtime_link_library_directories, RpathDirs0, !IO),
+ RpathDirs = list.map(quote_arg, RpathDirs0),
+ (
+ RpathDirs = [],
+ RpathOpts = ""
+ ;
+ RpathDirs = [_ | _],
+ globals.io_lookup_string_option(RpathSepOpt, RpathSep, !IO),
+ globals.io_lookup_string_option(RpathFlagOpt, RpathFlag, !IO),
+ RpathOpts0 = string.join_list(RpathSep, RpathDirs),
+ RpathOpts = RpathFlag ++ RpathOpts0
+ )
+ ;
+ RpathOpts = ""
+ ).
+
:- pred get_system_libs(linked_target_type::in, string::out, io::di, io::uo)
is det.
@@ -2113,7 +2148,7 @@
globals.io_lookup_bool_option(parallel, Parallel, !IO),
globals.io_get_gc_method(GCMethod, !IO),
UseThreadLibs = ( ( Parallel = yes ; GCMethod = gc_mps ) -> yes ; no ).
-
+
post_link_make_symlink_or_copy(ErrorStream, LinkTargetType, ModuleName,
Succeeded, MadeSymlinkOrCopy, !IO) :-
globals.io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs, !IO),
@@ -2451,7 +2486,7 @@
% strings to file names and then back, adding the specified Extension.
% (This conversion ensures that we follow the usual file naming
% conventions.)
-
+ %
:- pred join_module_list(list(string)::in, string::in, list(string)::out,
io::di, io::uo) is det.
@@ -2478,7 +2513,7 @@
%-----------------------------------------------------------------------------%
-:- pragma promise_pure(maybe_pic_object_file_extension/3).
+:- pragma promise_equivalent_clauses(maybe_pic_object_file_extension/3).
maybe_pic_object_file_extension(Globals::in, PIC::in, Ext::out) :-
(
@@ -2765,6 +2800,47 @@
io.write_string(Stream, CFlags, !IO).
%-----------------------------------------------------------------------------%
+%
+% Library link flags
+%
+
+output_library_link_flags(Stream, !IO) :-
+
+ % We output the library link flags as they are for when we are linking
+ % an executable.
+ LinkTargetType = executable,
+ RpathFlagOpt = linker_rpath_flag,
+ RpathSepOpt = linker_rpath_separator,
+
+ globals.io_lookup_accumulating_option(link_library_directories,
+ LinkLibraryDirectoriesList, !IO),
+ globals.io_lookup_string_option(linker_path_flag, LinkerPathFlag,
+ !IO),
+ join_quoted_string_list(LinkLibraryDirectoriesList, LinkerPathFlag, "",
+ " ", LinkLibraryDirectories),
+ get_runtime_library_path_opts(LinkTargetType, RpathFlagOpt, RpathSepOpt,
+ RpathOpts, !IO),
+ get_link_libraries(MaybeLinkLibraries, !IO),
+ (
+ MaybeLinkLibraries = yes(LinkLibrariesList),
+ join_quoted_string_list(LinkLibrariesList, "", "", " ",
+ LinkLibraries)
+ ;
+ MaybeLinkLibraries = no,
+ LinkLibraries = ""
+ ),
+ % Find the Mercury standard libraries.
+ get_mercury_std_libs(LinkTargetType, MercuryStdLibs, !IO),
+ get_system_libs(LinkTargetType, SystemLibs, !IO),
+ string.append_list([
+ LinkLibraryDirectories, " ",
+ RpathOpts, " ",
+ LinkLibraries, " ",
+ MercuryStdLibs, " ",
+ SystemLibs], LinkFlags),
+ io.write_string(Stream, LinkFlags, !IO).
+
+%-----------------------------------------------------------------------------%
:- func this_file = string.
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.485
diff -u -r1.485 mercury_compile.m
--- compiler/mercury_compile.m 16 Jan 2009 02:31:22 -0000 1.485
+++ compiler/mercury_compile.m 16 Jan 2009 04:33:06 -0000
@@ -401,6 +401,8 @@
OutputLibGrades),
globals.lookup_bool_option(Globals, output_cc, OutputCC),
globals.lookup_bool_option(Globals, output_cflags, OutputCFlags),
+ globals.lookup_bool_option(Globals, output_library_link_flags,
+ OutputLibraryLinkFlags),
globals.lookup_bool_option(Globals, make, Make),
globals.lookup_maybe_string_option(Globals, generate_standalone_interface,
GenerateStandaloneInt),
@@ -445,6 +447,9 @@
; OutputCFlags = yes ->
io.stdout_stream(StdOut, !IO),
output_c_compiler_flags(StdOut, !IO)
+ ; OutputLibraryLinkFlags = yes ->
+ io.stdout_stream(StdOut, !IO),
+ output_library_link_flags(StdOut, !IO)
; GenerateMapping = yes ->
source_file_map.write_source_file_map(Args, !IO)
; GenerateStandaloneInt = yes(StandaloneIntBasename) ->
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.641
diff -u -r1.641 options.m
--- compiler/options.m 23 Dec 2008 01:37:38 -0000 1.641
+++ compiler/options.m 19 Jan 2009 05:16:56 -0000
@@ -187,6 +187,7 @@
; output_libgrades
; output_cc
; output_cflags
+ ; output_library_link_flags
% Auxiliary output options
; smart_recompilation
@@ -1080,9 +1081,8 @@
output_shared_lib_link_command - bool(no),
output_libgrades - bool(no),
output_cc - bool(no),
- output_cflags - bool(no)
-
-
+ output_cflags - bool(no),
+ output_library_link_flags - bool(no)
]).
option_defaults_2(aux_output_option, [
% Auxiliary Output Options
@@ -1908,6 +1908,7 @@
long_option("output-libgrades", output_libgrades).
long_option("output-cc", output_cc).
long_option("output-cflags", output_cflags).
+long_option("output-library-link-flags", output_library_link_flags).
% aux output options
long_option("smart-recompilation", smart_recompilation).
@@ -3493,7 +3494,13 @@
"\tPrint the name of the C compiler to the standard output.",
"--output-cflags",
"\tPrint the flags with which the C compiler will be invoked",
- "\tto the standard output."
+ "\tto the standard output.",
+ "--output-library-link-flags",
+ "\tPrint the flags that are passed to linker in order to link",
+ "\tagainst the current set of libraries. This includes the",
+ "\tstandard library as well as any other libraries specified",
+ "\tvia the --ml option. The flags are printed to the standard",
+ "\toutput."
]).
:- pred options_help_aux_output(io::di, io::uo) is det.
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.580
diff -u -r1.580 user_guide.texi
--- doc/user_guide.texi 3 Nov 2008 11:56:17 -0000 1.580
+++ doc/user_guide.texi 19 Jan 2009 05:14:58 -0000
@@ -6665,6 +6665,14 @@
Print the flags with which the C compiler will be invoked
to the standard output.
+ at sp 1
+ at item --output-library-link-flags
+ at findex --output-library-link-flags
+Print the flags that are passed to the linker in order to link
+against the current set of libraries. This includes the standard
+library as well as any other libraries specified via the
+ at samp{--ml} option. The flags are printed to the standard output.
+
@end table
@node Auxiliary output options
Index: samples/c_interface/standalone_c/Makefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/samples/c_interface/standalone_c/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- samples/c_interface/standalone_c/Makefile 18 Jun 2007 05:25:48 -0000 1.2
+++ samples/c_interface/standalone_c/Makefile 16 Jan 2009 06:42:52 -0000
@@ -32,11 +32,8 @@
# link them all together. Specific details concerning each step in the build
# process are discussed below. See c_main.c for details of how to invoke the
# stand-alone interface from C or C++ code.
-#
-# NOTE: the following example is statically linked against the Mercury
-# libraries. This is in order to make the example as portable as possible.
-# Shared libraries will also work with stand-alone interfaces on systems
-# that support them.
+
+MMC = mmc
all: c_main
@@ -48,6 +45,40 @@
#
GRADEOPT=
+# By default we link our application statically against the Mercury libraries.
+# If you wish to use the shared versions of the Mercury libraries, comment
+# out the next two lines and uncomment the two following them.
+#
+# Note that we specify the example mercury_lib library to the linker separately
+# here. This is because we have not installed it.
+#
+MERCURY_LINKAGE = --mercury-linkage static
+MERCURY_LIB_LDFLAGS = libmercury_lib.a
+
+# For using shared libraries. (Remember to comment out the versions
+# above if you use these.)
+#
+#MERCURY_LINKAGE = --mercury-linkage shared
+#MERCURY_LIB_LDFLAGS = -L. -Wl,-rpath . -lmercury_lib
+
+# Ask the Mercury compiler what C compiler we should use?
+#
+CC = $(shell $(MMC) --output-cc)
+
+# Ask the Mercury compiler what flags it passes to the C compiler?
+#
+CFLAGS=$(shell $(MMC) $(GRADEOPT) --output-cflags)
+
+# Ask the Mercury compiler what command it uses to invoke the linker when
+# creating an executable?
+#
+LD = $(shell $(MMC) --output-link-command)
+
+# Ask the Mercury compiler what flags it passes to the linker in order to link against
+# the selected set of Mercury libraries?
+#
+LIB_LDFLAGS = $(shell $(MMC) $(GRADEOPT) $(MERCURY_LINKAGE) --output-library-link-flags)
+
# Build the example Mercury library, mercury_lib.
# The dependency on the .init file is merely a convenience. It's a good
# one to choose since it will always be regenerated if one of the .m files
@@ -58,7 +89,7 @@
# library.
#
mercury_lib.init: mercury_lib.m
- mmc $(GRADEOPT) --make libmercury_lib
+ $(MMC) $(GRADEOPT) --make libmercury_lib
# The following rule creates the stand-alone interface to the mercury_lib
# library, Mercury standard library and Mercury runtime. Since we haven't
@@ -67,7 +98,7 @@
# `--mld' option to specify its location.
#
mercury_lib_int.o: mercury_lib.init
- mmc $(GRADEOPT) --mercury-linkage static --ml mercury_lib \
+ $(MMC) $(GRADEOPT) --ml mercury_lib \
--generate-standalone-interface mercury_lib_int
# We use the mgnuc script here rather than invoking gcc directly since
@@ -78,16 +109,15 @@
# the `-I' option.
#
c_main.o: c_main.c mercury_lib.init mercury_lib_int.o
- mgnuc $(GRADEOPT) -c c_main.c
+ $(CC) $(CFLAGS) -c c_main.c
# For similar reasons we use the ml script rather than invoking ld directly.
#
c_main: c_main.o mercury_lib_int.o mercury_lib.init
- ml $(GRADEOPT) --mercury-libs static -o c_main \
- c_main.o libmercury_lib.a mercury_lib_int.o
+ $(LD) -o c_main c_main.o $(MERCURY_LIB_LDFLAGS) mercury_lib_int.o $(LIB_LDFLAGS)
.PHONY: realclean
realclean:
- -mmc --make mercury_lib.realclean
+ -$(MMC) --make mercury_lib.realclean
/bin/rm -f mercury_lib_int.[cho] c_main.o c_main Deep.data
/bin/rm -rf Mercury
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list