mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
... because they are almost always passed together, and grouping them
makes this clear. Also, code with shorter argument lists is more readable.
compiler/options_file.m:
Define the types of the collective structures. Defined them here
because one of them is defined here, and all the others are
lists of strings.
compiler/make.make_info.m:
Store one of its collective structures instead of its components.
compiler/make.build.m:
compiler/make.get_module_dep_info.m:
compiler/make.library_install.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.top_level.m:
compiler/make.track_flags.m:
compiler/mercury_compile_args.m:
compiler/mercury_compile_main.m:
Conform to the changes above.
657 lines
23 KiB
Mathematica
657 lines
23 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2002-2012 The University of Melbourne.
|
|
% Copyright (C) 2013-2025 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: make.top_level.m.
|
|
% Main author: stayl.
|
|
%
|
|
% The top level of mmc --make.
|
|
%
|
|
% TODO:
|
|
% - distributed builds
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module make.top_level.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.maybe_util.
|
|
:- import_module make.make_info.
|
|
:- import_module make.options_file.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% make_process_compiler_args(ProgressStream, Globals, ArgPack, !IO):
|
|
%
|
|
% Build the targets specified by the non-option arguments in ArgPack,
|
|
% obeying the options in the rest of ArgPack.
|
|
%
|
|
:- pred make_process_compiler_args(io.text_output_stream::in, globals::in,
|
|
compiler_arg_pack::in, io::di, io::uo) is det.
|
|
|
|
:- pred make_top_targets(io.text_output_stream::in, globals::in,
|
|
maybe_keep_going::in, list(top_target_file)::in,
|
|
maybe_succeeded::in, maybe_succeeded::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module backend_libs.
|
|
:- import_module backend_libs.compile_target_code.
|
|
:- import_module backend_libs.link_target_code.
|
|
:- import_module libs.options.
|
|
:- import_module libs.timestamp.
|
|
:- import_module make.hash.
|
|
:- import_module make.index_set.
|
|
:- import_module make.module_target.
|
|
:- import_module make.program_target.
|
|
:- import_module make.timestamp.
|
|
:- import_module make.track_flags.
|
|
:- import_module make.util.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.file_names.
|
|
:- import_module parse_tree.maybe_error.
|
|
:- import_module parse_tree.module_cmds.
|
|
:- import_module parse_tree.write_error_spec.
|
|
|
|
:- import_module bool.
|
|
:- import_module dir.
|
|
:- import_module map.
|
|
:- import_module pair.
|
|
:- import_module set.
|
|
:- import_module string.
|
|
:- import_module version_array.
|
|
:- import_module version_hash_table.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
make_process_compiler_args(ProgressStream, Globals, ArgPack, !IO) :-
|
|
ArgPack = compiler_arg_pack(EnvOptFileVariables, EnvVarArgs,
|
|
OptionArgs, NonOptionArgs),
|
|
io.progname_base("mercury_compile", ProgName, !IO),
|
|
get_main_target_if_needed(ProgName, EnvOptFileVariables,
|
|
NonOptionArgs, MaybeTargets0),
|
|
report_any_absolute_targets(ProgName, MaybeTargets0, MaybeTargets),
|
|
(
|
|
MaybeTargets = error1(Specs),
|
|
io.stderr_stream(StdErr, !IO),
|
|
write_error_specs(StdErr, Globals, Specs, !IO)
|
|
;
|
|
MaybeTargets = ok1(Targets),
|
|
globals.lookup_bool_option(Globals, keep_going, KeepGoingBool),
|
|
( KeepGoingBool = no, KeepGoing = do_not_keep_going
|
|
; KeepGoingBool = yes, KeepGoing = do_keep_going
|
|
),
|
|
globals.lookup_int_option(Globals, analysis_repeat, AnalysisRepeat),
|
|
|
|
HashPredMI = module_name_hash,
|
|
ForwardMI = version_hash_table.init_default(HashPredMI),
|
|
ReverseMI = version_array.empty,
|
|
ModuleIndexMap = module_index_map(ForwardMI, ReverseMI, 0u),
|
|
|
|
HashPredDI = target_id_module_index_hash,
|
|
ForwardDI = version_hash_table.init_default(HashPredDI),
|
|
ReverseDI = version_array.empty,
|
|
TargetIndexMap = target_id_index_map(ForwardDI, ReverseDI, 0u),
|
|
|
|
TargetStatusMap = version_hash_table.init_default(target_id_hash),
|
|
|
|
% Accept and ignore `.depend' targets. `mmc --make' does not need
|
|
% a separate make depend step. The dependencies for each module
|
|
% are regenerated on demand.
|
|
list.filter(
|
|
( pred(Target::in) is semidet :-
|
|
not string.suffix(Target, ".depend"),
|
|
not string.suffix(Target, ".depend_ints")
|
|
), Targets, NonDependTargets),
|
|
% Classify the remaining targets.
|
|
list.map(classify_target(Globals), NonDependTargets,
|
|
ClassifiedTargets),
|
|
ClassifiedTargetSet = set.list_to_set(ClassifiedTargets),
|
|
|
|
globals.get_maybe_stdlib_grades(Globals, MaybeStdLibGrades),
|
|
Params = compiler_params(EnvOptFileVariables, EnvVarArgs, OptionArgs),
|
|
TimestampMap = init_target_file_timestamp_map,
|
|
MakeInfo0 = init_make_info(MaybeStdLibGrades, KeepGoing, Params,
|
|
ClassifiedTargetSet, AnalysisRepeat, TimestampMap,
|
|
ModuleIndexMap, TargetIndexMap, TargetStatusMap),
|
|
|
|
% Build the targets, stopping on any errors if `--keep-going'
|
|
% was not set.
|
|
make_top_targets(ProgressStream, Globals, KeepGoing, ClassifiedTargets,
|
|
succeeded, Succeeded, MakeInfo0, _MakeInfo, !IO),
|
|
maybe_set_exit_status(Succeeded, !IO)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred get_main_target_if_needed(string::in, env_optfile_variables::in,
|
|
list(string)::in, maybe1(list(string))::out) is det.
|
|
|
|
get_main_target_if_needed(ProgName, EnvOptFileVariables, Targets0,
|
|
MaybeTargets) :-
|
|
(
|
|
Targets0 = [_ | _],
|
|
MaybeTargets = ok1(Targets0)
|
|
;
|
|
Targets0 = [],
|
|
lookup_main_target(EnvOptFileVariables, MaybeMainTargets),
|
|
(
|
|
MaybeMainTargets = ok1(MainTargets),
|
|
(
|
|
MainTargets = [_ | _],
|
|
MaybeTargets = ok1(MainTargets)
|
|
;
|
|
MainTargets = [],
|
|
Pieces = [fixed(ProgName), suffix(":"),
|
|
words("*** Error: no target or MAIN_TARGET specified."),
|
|
nl],
|
|
Spec = no_ctxt_spec($pred, severity_error, phase_options,
|
|
Pieces),
|
|
MaybeTargets = error1([Spec])
|
|
)
|
|
;
|
|
MaybeMainTargets = error1(Specs),
|
|
MaybeTargets = error1(Specs)
|
|
)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
% Ensure none of the targets contains the directory_separator.
|
|
% Such targets are not supported by the rest of the code.
|
|
%
|
|
:- pred report_any_absolute_targets(string::in, maybe1(list(string))::in,
|
|
maybe1(list(string))::out) is det.
|
|
|
|
report_any_absolute_targets(ProgName, MaybeTargets0, MaybeTargets) :-
|
|
(
|
|
MaybeTargets0 = error1(_),
|
|
MaybeTargets = MaybeTargets0
|
|
;
|
|
MaybeTargets0 = ok1(Targets),
|
|
IsAbsoluteFileName =
|
|
( pred(Target::in) is semidet :-
|
|
string.contains_char(Target, dir.directory_separator)
|
|
),
|
|
list.filter(IsAbsoluteFileName, Targets, AbsTargets),
|
|
(
|
|
AbsTargets = [],
|
|
MaybeTargets = MaybeTargets0
|
|
;
|
|
AbsTargets = [_ | _],
|
|
AbsTargetSpecs =
|
|
list.map(report_target_with_dir_component(ProgName),
|
|
AbsTargets),
|
|
MaybeTargets = error1(AbsTargetSpecs)
|
|
)
|
|
).
|
|
|
|
:- func report_target_with_dir_component(string, string) = error_spec.
|
|
|
|
report_target_with_dir_component(ProgName, Target) = Spec :-
|
|
Pieces = [fixed(ProgName), suffix(":"),
|
|
words("a make target may not contain a directory component,"),
|
|
words("but"), quote(Target), words("does."), nl],
|
|
Spec = no_ctxt_spec($pred, severity_error, phase_make_target, Pieces).
|
|
|
|
%---------------------%
|
|
|
|
make_top_targets(_ProgressStream, _Globals, _KeepGoing, [],
|
|
!Succeeded, !Info, !IO).
|
|
make_top_targets(ProgressStream, Globals, KeepGoing, [Target | Targets],
|
|
!Succeeded, !Info, !IO) :-
|
|
make_top_target(ProgressStream, Globals, Target, TargetSucceeded,
|
|
!Info, !IO),
|
|
should_we_stop_or_continue(KeepGoing, TargetSucceeded, StopOrContinue,
|
|
!Succeeded),
|
|
(
|
|
StopOrContinue = soc_stop
|
|
;
|
|
StopOrContinue = soc_continue,
|
|
make_top_targets(ProgressStream, Globals, KeepGoing, Targets,
|
|
!Succeeded, !Info, !IO)
|
|
).
|
|
|
|
:- pred make_top_target(io.text_output_stream::in, globals::in,
|
|
top_target_file::in, maybe_succeeded::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
make_top_target(ProgressStream, Globals, Target, Succeeded, !Info, !IO) :-
|
|
Target = top_target_file(ModuleName, TargetType),
|
|
globals.lookup_bool_option(Globals, make_track_flags, TrackFlags),
|
|
get_error_output_stream(Globals, ModuleName, ErrorStream, !IO),
|
|
(
|
|
TrackFlags = no,
|
|
TrackFlagsSucceeded = succeeded
|
|
;
|
|
TrackFlags = yes,
|
|
make_track_flags_files(ErrorStream, ProgressStream, Globals,
|
|
ModuleName, TrackFlagsSucceeded, !Info, !IO)
|
|
),
|
|
(
|
|
TrackFlagsSucceeded = succeeded,
|
|
(
|
|
TargetType = module_target(ModuleTargetType),
|
|
TargetFile = target_file(ModuleName, ModuleTargetType),
|
|
make_module_target([], ProgressStream, Globals,
|
|
merc_target(TargetFile), Succeeded, !Info, !IO)
|
|
;
|
|
TargetType = linked_target(LinkedTargetType),
|
|
LinkedTargetFile =
|
|
linked_target_file(ModuleName, LinkedTargetType),
|
|
make_linked_target(ProgressStream, Globals, LinkedTargetFile,
|
|
Succeeded, !Info, [], Specs, !IO),
|
|
write_error_specs(ErrorStream, Globals, Specs, !IO)
|
|
;
|
|
TargetType = misc_target(MiscTargetType),
|
|
make_misc_target(ProgressStream, Globals,
|
|
ModuleName - MiscTargetType, Succeeded, !Info, [], Specs, !IO),
|
|
write_error_specs(ErrorStream, Globals, Specs, !IO)
|
|
)
|
|
;
|
|
TrackFlagsSucceeded = did_not_succeed,
|
|
Succeeded = did_not_succeed
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred classify_target(globals::in, string::in, top_target_file::out) is det.
|
|
|
|
classify_target(Globals, TargetName, TopTargetFile) :-
|
|
( if
|
|
string.length(TargetName, NameLength),
|
|
search_backwards_for_dot(TargetName, NameLength, DotLocn),
|
|
string.split(TargetName, DotLocn, ModuleNameStr0, ExtStr),
|
|
classify_extstr_target(Globals, ModuleNameStr0, ExtStr,
|
|
TopTargetFilePrime)
|
|
then
|
|
TopTargetFile = TopTargetFilePrime
|
|
else
|
|
( if string.remove_prefix("lib", TargetName, ModuleNameStr) then
|
|
file_name_to_module_name(ModuleNameStr, ModuleName),
|
|
TargetType = misc_target(misc_target_build_library)
|
|
else
|
|
file_name_to_module_name(TargetName, ModuleName),
|
|
TargetType = linked_target(get_executable_type(Globals))
|
|
),
|
|
TopTargetFile = top_target_file(ModuleName, TargetType)
|
|
).
|
|
|
|
:- pred classify_extstr_target(globals::in, string::in, string::in,
|
|
top_target_file::out) is semidet.
|
|
|
|
classify_extstr_target(Globals, ModuleNameStr0, ExtStr, TopTargetFile) :-
|
|
( if
|
|
fixed_extension_top_target_file(Globals, ModuleNameStr0, ExtStr,
|
|
TopTargetFilePrime)
|
|
then
|
|
TopTargetFile = TopTargetFilePrime
|
|
else
|
|
mapped_extension_top_target_file(Globals, ModuleNameStr0, ExtStr,
|
|
TopTargetFile)
|
|
).
|
|
|
|
:- pred fixed_extension_top_target_file(globals::in, string::in, string::in,
|
|
top_target_file::out) is semidet.
|
|
|
|
fixed_extension_top_target_file(Globals, ModuleNameStr, ExtStr,
|
|
TopTargetFile) :-
|
|
(
|
|
(
|
|
ExtStr = ".m",
|
|
ModuleTarget = module_target_source
|
|
;
|
|
ExtStr = ".err",
|
|
ModuleTarget = module_target_errors
|
|
;
|
|
ExtStr = ".int0",
|
|
ModuleTarget = module_target_int0
|
|
;
|
|
ExtStr = ".int",
|
|
ModuleTarget = module_target_int1
|
|
;
|
|
ExtStr = ".int2",
|
|
ModuleTarget = module_target_int2
|
|
;
|
|
ExtStr = ".int3",
|
|
ModuleTarget = module_target_int3
|
|
;
|
|
ExtStr = ".opt",
|
|
ModuleTarget = module_target_opt
|
|
;
|
|
ExtStr = ".mih",
|
|
ModuleTarget = module_target_c_header(header_mih)
|
|
;
|
|
ExtStr = ".mh",
|
|
ModuleTarget = module_target_c_header(header_mh)
|
|
;
|
|
ExtStr = ".c",
|
|
ModuleTarget = module_target_c_code
|
|
;
|
|
ExtStr = ".cs",
|
|
ModuleTarget = module_target_csharp_code
|
|
;
|
|
ExtStr = ".csharp",
|
|
% For a long time, until 2023 oct 5, we treated the ".cs" target
|
|
% name as the build-all target for C files, so we accepted
|
|
% ".csharp" as the target name for C# files. Keep the synonym
|
|
% for a while longer to give people time to update their
|
|
% projects and habits.
|
|
ModuleTarget = module_target_csharp_code
|
|
;
|
|
ExtStr = ".java",
|
|
ModuleTarget = module_target_java_code
|
|
;
|
|
ExtStr = ".class",
|
|
ModuleTarget = module_target_java_class_code
|
|
;
|
|
ExtStr = ".target",
|
|
grade_specific_target_type(Globals, ModuleTarget)
|
|
;
|
|
ExtStr = ".track_flags",
|
|
ModuleTarget = module_target_track_flags
|
|
;
|
|
ExtStr = ".xml",
|
|
ModuleTarget = module_target_xml_doc
|
|
;
|
|
ExtStr = ".analysis",
|
|
ModuleTarget = module_target_analysis_registry
|
|
),
|
|
TargetType = module_target(ModuleTarget)
|
|
;
|
|
% This block of unifications is required by the fact that
|
|
% switch detection looks into two levels of disjunctions.
|
|
( ExtStr = ".all_ms"
|
|
; ExtStr = ".ms"
|
|
; ExtStr = ".all_errs"
|
|
; ExtStr = ".errs"
|
|
; ExtStr = ".all_int0s"
|
|
; ExtStr = ".int0s"
|
|
; ExtStr = ".all_ints"
|
|
; ExtStr = ".ints"
|
|
; ExtStr = ".all_int2s"
|
|
; ExtStr = ".int2s"
|
|
; ExtStr = ".all_int3s"
|
|
; ExtStr = ".int3s"
|
|
; ExtStr = ".all_opts"
|
|
; ExtStr = ".opts"
|
|
; ExtStr = ".all_cs"
|
|
; ExtStr = ".all_css"
|
|
; ExtStr = ".css"
|
|
; ExtStr = ".all_csharps"
|
|
; ExtStr = ".csharps"
|
|
; ExtStr = ".all_javas"
|
|
; ExtStr = ".javas"
|
|
; ExtStr = ".all_classs"
|
|
; ExtStr = ".classs"
|
|
; ExtStr = ".targets"
|
|
; ExtStr = ".all_targets"
|
|
; ExtStr = ".all_track_flagss"
|
|
; ExtStr = ".track_flagss"
|
|
; ExtStr = ".all_xmls"
|
|
; ExtStr = ".xmls"
|
|
; ExtStr = ".all_analysiss"
|
|
; ExtStr = ".analysiss"
|
|
),
|
|
(
|
|
( ExtStr = ".all_ms"
|
|
; ExtStr = ".ms"
|
|
),
|
|
ModuleTarget = module_target_source
|
|
;
|
|
( ExtStr = ".all_errs"
|
|
; ExtStr = ".errs"
|
|
),
|
|
ModuleTarget = module_target_errors
|
|
;
|
|
( ExtStr = ".all_int0s"
|
|
; ExtStr = ".int0s"
|
|
),
|
|
ModuleTarget = module_target_int0
|
|
;
|
|
( ExtStr = ".all_ints"
|
|
; ExtStr = ".ints"
|
|
),
|
|
ModuleTarget = module_target_int1
|
|
;
|
|
( ExtStr = ".all_int2s"
|
|
; ExtStr = ".int2s"
|
|
),
|
|
ModuleTarget = module_target_int2
|
|
;
|
|
( ExtStr = ".all_int3s"
|
|
; ExtStr = ".int3s"
|
|
),
|
|
ModuleTarget = module_target_int3
|
|
;
|
|
( ExtStr = ".all_opts"
|
|
; ExtStr = ".opts"
|
|
),
|
|
ModuleTarget = module_target_opt
|
|
% Not yet implemented. `build_all' targets are only used by
|
|
% tools/bootcheck, so it doesn't really matter.
|
|
% ;
|
|
% ( ExtStr = ".all_mihs"
|
|
% ; ExtStr = ".mihs"
|
|
% ),
|
|
% ModuleTarget = module_target_c_header(header_mih)
|
|
% ;
|
|
% ( ExtStr = ".all_mhs"
|
|
% ; ExtStr = ".mhs"
|
|
% ),
|
|
% ModuleTarget = module_target_c_header(header_mh)
|
|
;
|
|
( ExtStr = ".all_cs"
|
|
% ; ExtStr = ".cs" % Duplicates C# target.
|
|
),
|
|
ModuleTarget = module_target_c_code
|
|
;
|
|
( ExtStr = ".all_css"
|
|
; ExtStr = ".css"
|
|
),
|
|
ModuleTarget = module_target_csharp_code
|
|
;
|
|
( ExtStr = ".all_csharps"
|
|
; ExtStr = ".csharps"
|
|
),
|
|
% For a long time, until 2023 oct 5, we treated the ".cs" target
|
|
% name as the build-all target for C files, so we accepted
|
|
% ".csharp" as the target name for C# files. Keep the synonym
|
|
% for a while longer to give people time to update their
|
|
% projects and habits.
|
|
ModuleTarget = module_target_csharp_code
|
|
;
|
|
( ExtStr = ".all_javas"
|
|
; ExtStr = ".javas"
|
|
),
|
|
ModuleTarget = module_target_java_code
|
|
;
|
|
% We should s/classs/classes/ here, but this requires
|
|
% documentation and announcement, as well as updating all existing
|
|
% references to the old spelling in the Mercury system.
|
|
( ExtStr = ".all_classs"
|
|
; ExtStr = ".classs"
|
|
),
|
|
ModuleTarget = module_target_java_class_code
|
|
;
|
|
( ExtStr = ".targets"
|
|
; ExtStr = ".all_targets"
|
|
),
|
|
grade_specific_target_type(Globals, ModuleTarget)
|
|
;
|
|
( ExtStr = ".all_track_flagss"
|
|
; ExtStr = ".track_flagss"
|
|
),
|
|
ModuleTarget = module_target_track_flags
|
|
;
|
|
( ExtStr = ".all_xmls"
|
|
; ExtStr = ".xmls"
|
|
),
|
|
ModuleTarget = module_target_xml_doc
|
|
;
|
|
% We should s/analysiss/analyses/ here, but this requires
|
|
% documentation and announcement, as well as updating all existing
|
|
% references to the old spelling in the Mercury system.
|
|
( ExtStr = ".all_analysiss"
|
|
; ExtStr = ".analysiss"
|
|
),
|
|
ModuleTarget = module_target_analysis_registry
|
|
),
|
|
TargetType = misc_target(misc_target_build_all(ModuleTarget))
|
|
;
|
|
(
|
|
ExtStr = ".check",
|
|
MiscTarget = misc_target_build_all(module_target_errors)
|
|
;
|
|
ExtStr = ".doc",
|
|
MiscTarget = misc_target_build_xml_docs
|
|
;
|
|
ExtStr = ".analyse",
|
|
MiscTarget = misc_target_build_analyses
|
|
;
|
|
ExtStr = ".clean",
|
|
MiscTarget = misc_target_clean
|
|
;
|
|
ExtStr = ".realclean",
|
|
MiscTarget = misc_target_realclean
|
|
),
|
|
TargetType = misc_target(MiscTarget)
|
|
),
|
|
file_name_to_module_name(ModuleNameStr, ModuleName),
|
|
TopTargetFile = top_target_file(ModuleName, TargetType).
|
|
|
|
% XXX This predicate is intended to allow the tests in the recompilation
|
|
% directory to build target files *without* compiling or linking them,
|
|
% thus avoiding the disabling of smart recompilation by the
|
|
% maybe_disable_smart_recompilation predicate in handle_options.m.
|
|
% However, that would be worthwhile only *after* the infrastructure
|
|
% of that test directory has been converted to use mmc --make directly,
|
|
% *without* going through mmake.
|
|
%
|
|
% The extensions that this predicate is used for will need to be documented
|
|
% only when that actually happens.
|
|
%
|
|
% For more info, see the comment in tests/recompilation/Mmakefile
|
|
% on the code that disables all the tests there in Java and C# grades.
|
|
%
|
|
:- pred grade_specific_target_type(globals::in, module_target_type::out)
|
|
is det.
|
|
|
|
grade_specific_target_type(Globals, ModuleTargetType) :-
|
|
globals.get_target(Globals, Target),
|
|
(
|
|
Target = target_c,
|
|
ModuleTargetType = module_target_c_code
|
|
;
|
|
Target = target_java,
|
|
ModuleTargetType = module_target_java_code
|
|
;
|
|
Target = target_csharp,
|
|
ModuleTargetType = module_target_csharp_code
|
|
).
|
|
|
|
:- pred mapped_extension_top_target_file(globals::in, string::in, string::in,
|
|
top_target_file::out) is semidet.
|
|
|
|
mapped_extension_top_target_file(Globals, ModuleNameStr0, ExtStr,
|
|
TopTargetFile) :-
|
|
get_linked_target_ext_map(Globals, LinkedtargetExtMap),
|
|
map.search(LinkedtargetExtMap, ExtStr, LinkedTargetExtInfo),
|
|
LinkedTargetExtInfo = linked_target_ext_info(_, LinkedTargetKind),
|
|
% target_type_to_maybe_target_extension and the following code represent
|
|
% the same relationship between targets and suffixes, but in different
|
|
% directions, and for slightly different sets of targets. (For example,
|
|
% there is no extension that generates module_target_fact_table_object
|
|
% as a target.) Where they talk about the same targets, their codes
|
|
% should be kept in sync.
|
|
(
|
|
(
|
|
LinkedTargetKind = ltk_object_file,
|
|
ModuleTargetType = module_target_object_code(non_pic)
|
|
;
|
|
LinkedTargetKind = ltk_pic_object_file,
|
|
ModuleTargetType = module_target_object_code(pic)
|
|
),
|
|
ModuleNameStr = ModuleNameStr0,
|
|
TargetType = module_target(ModuleTargetType)
|
|
;
|
|
(
|
|
LinkedTargetKind = ltk_all_object_file,
|
|
ModuleTargetType = module_target_object_code(non_pic)
|
|
;
|
|
LinkedTargetKind = ltk_all_pic_object_file,
|
|
ModuleTargetType = module_target_object_code(pic)
|
|
),
|
|
ModuleNameStr = ModuleNameStr0,
|
|
TargetType = misc_target(misc_target_build_all(ModuleTargetType))
|
|
;
|
|
LinkedTargetKind = ltk_executable,
|
|
ModuleNameStr = ModuleNameStr0,
|
|
TargetType = linked_target(get_executable_type(Globals))
|
|
;
|
|
(
|
|
LinkedTargetKind = ltk_static_library,
|
|
TargetType = linked_target(static_library)
|
|
;
|
|
LinkedTargetKind = ltk_shared_library,
|
|
TargetType = linked_target(shared_library)
|
|
;
|
|
LinkedTargetKind = ltk_library_install,
|
|
TargetType = misc_target(misc_target_install_library)
|
|
;
|
|
LinkedTargetKind = ltk_library_install_gs_gas,
|
|
TargetType = misc_target(misc_target_install_library_gs_gas)
|
|
),
|
|
string.remove_prefix("lib", ModuleNameStr0, ModuleNameStr)
|
|
),
|
|
file_name_to_module_name(ModuleNameStr, ModuleName),
|
|
TopTargetFile = top_target_file(ModuleName, TargetType).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred search_backwards_for_dot(string::in, int::in, int::out) is semidet.
|
|
|
|
search_backwards_for_dot(String, Index, DotIndex) :-
|
|
string.unsafe_prev_index(String, Index, CharIndex, Char),
|
|
( if Char = ('.') then
|
|
DotIndex = CharIndex
|
|
else
|
|
search_backwards_for_dot(String, CharIndex, DotIndex)
|
|
).
|
|
|
|
:- func get_executable_type(globals) = linked_target_type.
|
|
|
|
get_executable_type(Globals) = ExecutableType :-
|
|
globals.get_target(Globals, CompilationTarget),
|
|
(
|
|
CompilationTarget = target_c,
|
|
ExecutableType = executable
|
|
;
|
|
CompilationTarget = target_csharp,
|
|
ExecutableType = csharp_executable
|
|
;
|
|
CompilationTarget = target_java,
|
|
ExecutableType = java_executable
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module make.top_level.
|
|
%---------------------------------------------------------------------------%
|