summaryrefslogtreecommitdiff
path: root/gcc/m2/m2-link-support.h
blob: a68b3c9cdc35740c5ae1051410681594ad9eecbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* Link support specs for GNU Modula-2.
   Copyright (C) 2019-2022 Free Software Foundation, Inc.
   Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* The subprograms used by Modula-2 to facilitate linking are:
   gm2l - parses the top level module and all other dependent
          modules.  It creates a dependency tree and emits a list
          of dependent modules.
   gm2lcc - generates a link command for all dependent modules or
            display module object filesystem location.
   gm2m - parses the top level module and all other dependent
          module and generates a Makefile from the import tree.
   gm2lgen - generate a C or C++ scaffold from the list of modules.
   gm2lorder - manipulate the dependent list of modules to force
               critcal runtime modules to be initialized at the
               beginning of the init sequence.  */

/* AS run the assembler with default options.  */

#define AS(INPUT,OUTPUT)  "as %a %Y " INPUT " -o " OUTPUT

/* GM2CC_OPTIONS a list of all CC options used by gm2 during the
   link scaffold generation.  */

#define GM2CC_OPTIONS "%{i*} %{v*} %{m*} %{g*} %{O*} %{fPIC} %{fpic} \
                       %{+e*} %{I*} %{MD} %{MMD} %{M} %{MM} %{MA} \
                       %{MT*} %{MF*} -quiet "

/* SCAFFOLDNAME is the basename of the scaffold C or C++ program
   which may be automatically generated by the linking process.  */

#define SCAFFOLDNAME "%b_m2"

/* RM_IF_NOSAVETEMP remove the next file if save-temps is absent.  */

#define RM_IF_NOSAVETEMP "%{!save-temps*:%d}"

/* GM2CC compile the link scaffold either with the C or C++
   compiler.  */

#define GM2CC(INPUT,OUTPUT) \
  "%{!fno-exceptions:cc1plus;:cc1} %1" GM2CC_OPTIONS " " INPUT " \
     -o " RM_IF_NOSAVETEMP SCAFFOLDNAME ".s \n\
  " AS(SCAFFOLDNAME ".s",OUTPUT) " "

/* GM2LCC invoke the sub program gm2lcc with the object path options
   and user supplied objects.  It will search for Modula-2 object
   if they are not already present on the command line.  The
   current module is contained in OBJECT and LST is a list of all
   the dependant modules.  */

#define GM2LCC(OBJECT,LST) \
  "gm2lcc %{fshared} %{fpic} %{fPIC} %{B*} %{L*} %{ftarget-ar=*} \
          %{ftarget-ranlib=*} \
          %{fobject-path=*} %{v} --exec --startup \
          " SCAFFOLDNAME "%O \
          %{!fshared:--ar %:objects() %:noobjects() -o " \
          RM_IF_NOSAVETEMP "%w%g.a } \
          " OBJECT " \
          %{fshared:%w%{o:%{o*}}%:nolink() %:objects() %:noobjects() \
            %:linkargs() } " LST " "

/* GM2LORDER run the gm2lorder sub program.  It generates a module
   list LST by parsing INPUT and all dependant modules.  */

#define GM2LORDER(INPUT,LST) \
  "gm2lorder %{fruntime-modules=*} " INPUT " -o " LST " \n"

/* GM2LGEN run the gm2lgen sub program which generates a C or C++
   scaffold (SCAFFOLDSRC).  It then compiles SCAFFOLDSRC and links
   it with all dependant modules in LST.  MAINOBJECT is the main
   module object name containing the scaffold.  */

#define GM2LGEN(LST,SCAFFOLDSRC,MAINOBJECT) \
  "gm2lgen %{fshared} %{fshared:--terminate --exit} \
           %{!fno-exceptions:-fcpp} " LST " -o " SCAFFOLDSRC " \n\
   " GM2L_COMBINE(LST,SCAFFOLDSRC,MAINOBJECT)

/* GM2L_COMBINE compiles the scaffold SCAFFOLDSRC and links all dependant
   modules in LST.  MAINOBJECT is the main module object containing
   the scaffold.  */

#define GM2L_COMBINE(LST,SCAFFOLDSRC,MAINOBJECT) \
  GM2CC(SCAFFOLDSRC,MAINOBJECT) " \n\
   rm -f %w%d%g.a \n\
  " GM2LCC("--mainobject " MAINOBJECT,LST)

/* Pass the preprocessor options on the command line together with
   the exec prefix.  */

#define M2CPP "%{fcpp:-fcppbegin %:exec_prefix(cc1)" \
              "      -E -lang-asm -traditional-cpp " \
              "      %(cpp_unique_options) -fcppend}"

/* Generate a list of topologically sorted dependent modules.  */

#define GM2L(INPUT,OUTPUT) \
  "gm2l %{v} " M2CPP " %{I*} %{fdef=*} %{fmod=*} " OUTPUT " " INPUT " "

/* General GNU options.  */

#define GENERAL_OPTIONS "%{i*} %{f*} %{+e*} %{I*} %{MD} %{MMD} %{M} \
  %{MM} %{MA} %{MT*} %{MF*} %V"

/* Run the compiler using standard GNU options.  */

#define CC1GM2 "cc1gm2 " M2CPP " %(cc1_options) " GENERAL_OPTIONS

/*  Generate a swig interface file and exit.  */

#define SWIG "%{fswig:" CC1GM2 "%i \n\
                 %:exit()}"

/* Generate a basename.lst containing a list of all dependent modules
   for the project and exit.  */

#define MAKELIST "%{fmakelist:" GM2L("%i","%{!pipe:-o %g.l}") " |\n\
                     gm2lorder %{fruntime-modules=*} %{!pipe:%g.l} \
                       -o %b.lst \n\
                     %:exit()}"

/* Generate a scaffold from basename.lst and store the output source
   into SCAFFOLDNAME.cpp and exit.  */

#define MAKEINIT "%{fmakeinit:gm2lgen %{fshared} \
                     %{fshared:--terminate --exit} \
                     %{!fno-exceptions:-fcpp} %b.lst -o " \
                     SCAFFOLDNAME ".cpp \n\
                     %:exit()}"

/* Display the filesystem location of the all object files in the
   project list.  */

#define REPORT_OBJECTS "gm2lcc %{fshared} %{fpic} %{fPIC} %{B*} %{L*} \
                        %{ftarget-ar=*} %{ftarget-ranlib=*} \
                        %{fobject-path=*} %{v} -c "

/* Generate a list of modules used within a project and report the
   object file location and exit.  */

#define MODULES \
  "%{fmodules:%{fuselist:" REPORT_OBJECTS " %b.lst}" \
               "%{!fuselist:" GM2L("%i","%{!pipe:-o %g.l}") " |\n\
                              gm2lorder %{fruntime-modules=*} \
                                 %{!pipe:%g.l} -o %g.lst \n\
                            " REPORT_OBJECTS " %g.lst} \n\
     %:exit()}"

/* MODULA_PROJECT_SUPPORT contains a list of all project support
   sub components.  */

#define MODULA_PROJECT_SUPPORT  SWIG MAKELIST MAKEINIT MODULES

/* GM2 invoke cc1gm2 placing assembler output into OUTPUT given
   source file, INPUT.  */

#define GM2(INPUT,OUTPUT) CC1GM2 " -o " OUTPUT " " INPUT

/* GEN_SCAFFOLD_SRC generates the string SCAFFOLDNAME ".cpp"
   marking it for deletion if -fmakeinit is absent.  */

#define GEN_SCAFFOLD_SRC \
     "%{fmakeinit:" SCAFFOLDNAME ".cpp;:" \
                    RM_IF_NOSAVETEMP SCAFFOLDNAME ".cpp}"

/* M2LINK compile main module (providing absense of -fonlylink)
   and link all project dependent modules.  */

#define M2LINK \
  "%{!S:%{!gm2gcc:%{!fonlylink:" GM2("%i",RM_IF_NOSAVETEMP "%g.s") " \n\
                               " AS("%g.s","%w%b%O") " } \n\
                   %{!fuselist:" GM2L("%i"," -o %g.l ") " \n\
                               " GM2LORDER("%g.l","%g.lst") " \n\
                   " GM2LGEN("%{fuselist:%b.lst;:%g.lst}",\
                             GEN_SCAFFOLD_SRC,\
			     RM_IF_NOSAVETEMP SCAFFOLDNAME "%O") "}}\n\
    }"

/* MODULA_LINK_SUPPORT only invoke link subprocesses if no -c option.  */

#define MODULA_LINK_SUPPORT  "%{!c:" M2LINK "}"