Hi Ian, thanks for your reply.
1. First I need to use my current build machine, Linux,
to first of all convert the i370.md into insn*.c files, then
generate an xgcc. The xgcc would be capable of producing
i370 code so long as I use the "-S" option. It doesn't really
matter how this xgcc was created (ie using non-C90
stuff like fork available on my build machine).
2. It is now (at the Alaskan stage) that I need a different sort
of config.h/auto-host.h that excludes things like fork. I can
present my i370 include files here, that only include C90
functions. It is at this stage that I need it to invoke xgcc
(still on the build machine), but it will be with the -S option,
so there will be no .o files (although I could perhaps fake
that via a scipt to keep "make" happy) and no executable
built. The "fake" script could generate JCL at the same time.
The C90 library (for MVS) also needs to be cross-compiled
here.
3. Then I need to assemble all the assembler on real i370
(MVS). It is at this point that a real host (ie on i370 MVS)
xgcc is built.
4. Then I can use that xgcc (on MVS) to compile arbitary
C programs. Technically I could have had a requirement
for this i370-mvs host compiler to produce say sparc target
code.
What most people do is:
* Configure gcc as a cross-compiler.
So this would not be considered a Canadian Cross after all,
and with configure I only change the target, not the host?
* Write a cross-assembler and cross-linker.
Sure, and that's what I'm trying to avoid. I have a perfectly working
assembler and linker on MVS already. It's been working for several
decades.
* Copy header files and libraries from the host (MVS).
That's fine. And use the --with-root option of configure to get
them used?
Now you have a complete cross-toolchain running on a supported host
which can produce executables which run on MVS.
It's a can of worms just trying to copy MVS load modules. There's
meta-data in 2 different places and it needs to be packaged.
* Use that cross-toolchain to build a version of gcc which runs on
MVS. At this step you port gcc to work on MVS.
* Run that gcc on MVS.
(Note that you mention fork, but as you probably know the gcc code
never actually calls fork. It calls the pexecute routines in
libiberty. Those routines have been ported to several different
hosts, including MS-DOS. If you port them to MVS, then you don't have
to worry about fork.)
I spent several minutes going through the config.h looking at the
"detected" functions to find a good example. Maybe I should I
have getrlimit or getrusage or fputs_unlocked instead.
To fit into the standard Canadian Cross 3-step model, I need
to either collapse steps 2 and 3 into 1 theoretical step, executed
across 2 platforms (compile on one, assemble on another),
Right, people normally do this by using a cross-assembler and
cross-linker.
Ok.
I suspect that it will only take 20 lines or similar of intrusive
Makefile/shell script changes to shoe-horn my way into the
existing gcc methodology. All I need to do is force it to use
my C90 headers at the right spot, so that it stops thinking
that I have fork etc, and stop it trying to build an executable.
Can someone tell me where to put those 20 lines?
One way to shoe-horn those lines in would be to make your
cross-assembler and cross-linker actually be shell scripts.
Ok, that's no problem.
They
would copy the files to MVS, run the real assembler and linker, and
copy the output back.
I might theoretically be able to do such a thing, but that's not what I'm
after. I'm just after 200+ assembler files to be produced so that I can
zip them up and take them to a real MVS site or whatever to get
compiled. It looks like someone just wrote a C compiler in
370 assembler, which is now all natural MVS (the objective of the
exercise).
That would be more than 20 lines, but it seems
doable to me.
Actually, that would be 0 lines of intrusive code (ie changing GCC
itself).
But I don't understand the bit about C90 headers. gcc doesn't need
fork, but it does need a way to execute other programs.
No, I use intrusive code to convert the pexecute call into a static
call to cc1 (effectively - I actually intercept it within gcc itself, see
below). And that is why I need a Makefile target that includes
all the object code. Because I compile the 450,000 lines of C code
into 850,000 lines of assembler code to produce a 3.4 MB gcc load
module for MVS. Those figures are from gcc 3.4.6.
BFN. Paul.
***************
*** 2610,2615 ****
--- 2623,2631 ----
static int
execute (void)
{
+ #ifdef SINGLE_EXECUTABLE
+ int ret_code = 0;
+ #endif
int i;
int n_commands; /* # of command. */
char *string;
***************
*** 2756,2761 ****
--- 2772,2792 ----
char *errmsg_fmt, *errmsg_arg;
const char *string = commands[i].argv[0];
+ #ifdef SINGLE_EXECUTABLE
+ {
+ int cnt = 0;
+
+ while (commands[i].argv[cnt] != NULL)
+ {
+ cnt++;
+ }
+ if (strcmp(string, "cc1") == 0)
+ {
+ ret_code = toplev_main(cnt, commands[i].argv);
+ if (ret_code != 0) break;
+ }
+ }
+ #else
/* For some bizarre reason, the second argument of execvp() is
char *const *, not const char *const *. */
commands[i].pid = pexecute (string, (char *const *)
commands[i].argv,