whm@megaron.UUCP (03/21/86)
I just installed C++ on our 4.3bsd VAXs and it didn't go too smoothly. I looked through the accumulated news in this group and there seem to be people that are running C++ on BSD systems and since there's been no mention of any others having any trouble installing on BSD systems, I was wondering if I managed to screw things up somehow. The problems seemed to stem from differences in Sys5 and BSD make and sh. For example, the instructions say to "make scratch" and issuing this command executes the following: cd scratch; CC=CC BSD=1 CCFLAGS="-O -DBSD" Oops! Looks like it got the variables set ok. If it had only remembered to do the make! We've got the BRL Sys5 package and using its make got around the problems with BSD make. In the CC script itself, when run with /bin/sh, you get a cryptic error about -a being an unrecognized operator for "test". Running with Sys5 sh fixes this. Further along in CC, the command "CC -o x x.c" eventually tries to do something like: cc -c -o x x..c mv x..o x.o With BSD cc, the output file lands in "x", not x..o. With Sys5 cc, the output goes to x..o; -o is passed on to the loader (if called). Also, there was no man page for CC other than the one included in the hardcopy documentation. Am I the only person who has encountered these problems with a BSD installation? If not, does anybody have a CC that allows the BSD cc behavior?
jon@cit-vax.Caltech.Edu (Jonathan P. Leech) (03/24/86)
Summary: Expires: Sender: Followup-To: Organization : California Institute of Technology Keywords: C++, porting, BSD, UTS, Sun, IBM WARNING: The following is a LONG (~440 lines) message about problems and experiences porting C++. Hit 'n' now unless you are having problems getting the new release of C++ running. The following is a summary of my experiences porting C++ Release 1.0 to three flavors of Unix on different hardware (VAX 11/780 4.2 BSD, Sun 2.0, IBM 4381 Amdahl UTS). Not everything said below applies to all of the machines. I cannot promise your problems will be the same, because I don't know how heavily the environment of our machines (or yours) has been modified. However, this material is accurate within these bounds and may resolve questions some people have had about installing C++. (And, to forestall any flames, Bjarne looked this over and approved it before I posted it). I) Shell scripts A) ``What's this ':' doing here?'' or, how do you get the right shell? Different versions of Unix have different conventions for identifing shell scripts. Unfortunately it appears to be impossible to come up with a single Bourne Shell script file which can be used with impunity on all Unix variants. Here's my summary of how systems deal with scripts: 4.2 BSD (VAX) Apparently all scripts are executed with sh UNLESS there is a line of the form '#!program' where 'program' is the alternative interpreter (such as /bin/csh) to run. No problems with the supplied scripts here. 4.2 BSD (Sun release 2.0) Apparently the default here is csh, not sh (my login shell is csh, which may be the cause) . There is in fact a line of the form '#!/bin/sh' in the 'CC' shell script, but it's on the SECOND line, so it's not recognized. It must be moved to the first line. The 'bsd.sed' shell script (if there's occasion to run it) must have the '#!/bin/sh' line added as the first line. Amdahl UTS In order to get a script executed by sh on this variant, it needs to have a ':' as the first character of the file (or at least this suffices). Even '#!/bin/sh' as the first line does not do the desired thing. So CC must be edited to add this. B) Nobody bothered to test `test'. There is a problem with the 'CC' shell script on many Unix systems. The 'test' program is used in CC in the following context (towards the end of the script): if test "$R" -a ! "$PLUSI" then rm $C fi unfortunately, strings as operands to 'test' do not work quite right on (at least) 4.2 BSD derived systems. In theory, an empty string "" should be equivalent to '0' or 'false' and the converse for a non-empty string. In fact this only works if the ONLY argument to test is a SINGLE empty (or not) string. To observe this, execute test "" -a "" on a 4.2 system and cringe. This behavior has been seen on VAX/4.2 BSD, Sun 4.2 BSD, VAX/4.3 BSD, and a version of Unix derived from Unix/TS and Unix/32V. Test appears to work properly on all the System III/System V Unixes (Unices? Unixi?) that I have access to. To correct this problem, change the 4 lines above to if test "$R" ; then if test ! "$PLUSI" ; then rm $C fi fi this is a bit more verbose, but works. C) But... how do you find the members? The source to cfront (the compiler portion of C++) comes in both C++ and C form, the latter to provide a way of bootstrapping cfront. The C version of cfront appears to be targeted for a System V Unix. In order to get cfront working properly on a 4.2 BSD system (in fact on any Unix system), the declaration of the 'FILE' aka '_iobuf' structure must be changed to correspond with with that on your system. Otherwise cfront will explode the first time it tries to do I/O. There is a supplied shell script 'bsd.sed' in the 'scratch' directory which is supposed to massage the C source to cfront by changing the declarations of FILE members. Unfortunately, it does not do the complete job; the '__iobuf__flag' member of FILE is a SHORT on 4.2 BSD, not a char. This might (or might not) make a difference, depending on the byte order and alignment constraints of the machine cfront is being compiled on. The following shell script corrects the declaration of FILE; it should be run in the 'scratch' directory AFTER bsd.sed. #!/bin/sh #ident "@(#)cfront:scratch/bsd42.sed (jon@csvax.caltech.edu) 1.0" echo "Fixing _iobuf structures for 4.2 BSD (__iobuf__flag member):" for f in */*..c do echo $f sed -e '/__iobuf__flag/s/char/short/' $f > temp$$ mv temp$$ $f done echo "We now return to our regularly scheduled C++ installation process" II) OS/utility bugs A) exit() vs. return() or, ``I don't CARE what you said! I'm exiting successfully anyway!'' The 'CC' script uses the exit status of the program 'munch' to determine if another pass of the loader needs to be made to properly call static constructors and destructors. Munch tries to return this status by just doing 'return 0' or 'return 1' from main(). Unfortunately, on several Unix variants (at least Sun 4.2 BSD and Amdahl UTS), ANY successful return from main causes an exit status of 0 instead of the returned value. For portability, change all 'return n' to 'exit(n)' in main() of lib/static/munch.c. B) Optimization On UTS, the optimizer pass of the C compiler (/lib/c2) core dumps while trying to compile parts of the C++ library (specifically lib/complex/io.c). Rather than try to figure out why, I just removed the -O flag from 'lib/mk/makefile' and 'makefile'. Bjarne says that many optimizers break on automagically generated C code such as that produced by cfront. C) Makefiles i) UTS Some parts of the supplied makefiles contain Bourne shell constructs. On UTS, the underlying shell that is invoked by 'make' is normally /bin/sh, but if the environment variable 'SHELL' is defined, that is used instead. If your login shell is NOT sh (say /usr/ucb/csh instead like mine), make will die when it feeds sh commands to a csh. Here are 2 solutions: (i) define SHELL=/bin/sh in the environment (ii) Add a line of the form 'MAKE=/bin/make SHELL=' to the top-level makefile. This will cause SHELL to be undefined when lib/mk/makefile is invoked, so sh will be used as desired. This is the preferred solution. ii) BSD When the top-level makefile invokes other makefiles, it uses the construct $(MAKE). Unfortunately, MAKE is NOT a predefined make variable in the 4.2 BSD implementation. To correct this, add a line of the form MAKE=/bin/make at the start of the top-level makefile. D) Ranlib (BSD) When an archive library (such as the libC.a created in the bootstrapping process) is copied, BSD systems sense the new modification date and complain that 'ranlib' has not been run on the archive since the copy. Ld will then exit with an unwarranted error code, which causes 'CC' to bomb out early. To correct this, once libC.a is installed in its final destination (/lib, /usr/lib, or whatever), re-run 'ranlib' on it. E) Dereferencing NULL This fix has been seen before but I'm putting it in for completeness. Make the following change in src/print.c: diff print.c.new print.c.orig 1452,1453c1452 < if ( (e2->tp == 0) || < Pptr(t1)->typ != Pptr(e2->tp)->typ) { --- > if (Pptr(t1)->typ != Pptr(e2->tp)->typ) { III) Random comments on porting C++ to different target machines A) Portability of the supplied C code to cfront As the AT&T installation guide briefly mentions, the declarations of the stdio FILE structure must be correct for the target system. That is not the only problem, however. Cfront needs to know about size and alignments of data types on the target architecture in order to generate correct C code for said machine. WARNING: the supplied C code for cfront is only promised to work on a 3B or VAX because of this. The only way to get around this is to first get cfront running on one of the machines the C code WILL work on, then cross-compile cfront (using an appropriate size/alignment file) for the target machine. Then you must move to the target machine and restart the process from 'scratch' (so to speak). B) Cross-compiling This assumes that you already have a working version of CC on some machine. If you don't, find some friendly person with a VAX or 3B. First, you have to find an appropriate size/alignment file for the target machine. Here are size/align files for Sun 2 (68000) and Amdahl UTS (IBM 370 architecture): Sun: char 1 1 short 2 2 int 4 2 2147483647 long 4 2 float 4 2 double 8 2 bit 8 32 struct 2 2 frame 2 2 top 0 0 word 4 0 wptr 4 2 bptr 4 2 UTS: char 1 1 short 2 2 int 4 4 2147483647 long 4 4 float 4 4 double 8 8 bptr 4 4 wptr 4 4 struct 1 1 ptr 4 4 bit 8 32 word 4 0 In addition, you may need to modify the 'DF_SENSITIVE' #define in src/size.h; I believe this should be 0 for Suns and 1 for UTS. Next, modify the 'fillscratch' entry in the makefile so that the invocations of CC include a '+xfile' where 'file' is the size/alignment file above. Here's how I did it for UTS (working from a VAX). I actually added a new target here: # This makes port files for UTS # UTS size/alignment file UTSDIR=/usr/src/c++/CC/UTS UAL=$(UTSDIR)/uts_size_align utsport: make sure the directories exist: if test ! -d uts/src; then mkdir uts/src; fi if test ! -d uts/mnch; then mkdir uts/mnch; fi if test ! -d uts/lib; then mkdir uts/lib; fi cd src; yacc gram.y cd uts/src; $(CC) +x$(UAL) -I$(UTSDIR) -I../../src -I../../incl \ -Fc -..c ../../src/*.c; cd uts/lib; $(CC) +x$(UAL) -I$(UTSDIR) -I../../lib/complex \ -I../../incl -Fc -..c ../../lib/new/*.c cd uts/lib; $(CC) +x$(UAL) -I$(UTSDIR) -I../../lib/complex \ -I../../incl -Fc -..c ../../lib/static/*.c rm uts/lib/munch..c #Dont need a real munch here: echo "main(){ exit(0); }" >uts/mnch/munch..c in the above segment of makefile, UTSDIR is the location of a directory containing (i) The size_alignment file (which is defined on the next line) (ii) /usr/include/stdio.h and /usr/include/ctype.h from the target machine. It is VITAL that these be included instead of the versions of stdio.h and ctype.h in the incl/ directory. Make a directory 'uts' and invoke 'make utsport'. When finished, uts/... will contain C code suitable for compiling under UTS. At this point, move the directory tree 'uts/...' from the host machine to the target. Move it into 'scratch/...' instead of 'uts/...' on the target, and proceed with the bootstrapping process. IMPORTANT NOTE: the generated cfront on the target machine will STILL require you to explicitly use the '+xsize_alignment_file' for the target because, despite the fact that it was itself compiled correctly, the default size/alignments built in are those for a vax. Two ways to work around this: (i) Modify the 'CC' script to ALWAYS use +x (putting the file in some publicly accessible place, probably the same directory as CC itself). (ii) Modify the file 'src/size.h' to contain the correct size/alignments for your target, then recompile cfront from the C++ source (again, using the +x option). The cfront which is generated will now have the correct size/alignments built in. It is also a good confidence-building measure for cfront to be able to successfully recompile itself on the target machine. This is my preferred solution. The include files installed in /usr/include/CC (or wherever) must be correct for the target. This could require a substantial amount of editing. 'incl/ctype.h' should be replaced with that from the target system's /usr/include. 'incl/stdio.h' should also be replaced; however, you must add the correct function prototypes for your system to stdio.h, or cfront cannot be recompiled successfully. The problem is that most stdio.h files have declarations of the form extern int setbuf(); unfortunately, C++ will interpret this as 'setbuf takes NO arguments'. When it then encounters an actual call to setbuf (containing 2 arguments), an error occurs. Since such calls appear in the source to cfront itself, it cannot be successfully recompiled without adding the function prototypes to CC's stdio.h. C) Compiling the library libC.a (in lib/*/*) When compiling the full libC.a, you must change 'incl/math.h' (which should become '/usr/include/CC/math.h') to include a correct definition of 'MAXFLOAT' for your system. Look in '/usr/include/math.h' for MAXFLOAT or HUGE (probably labelled appropriately). There are other conditional definitions of this nature in the CC include files, but they don't seem to affect compiling cfront and libC. I found that for some reason (probably a shell or make bug), the following changes had to be made in lib/mk/makefile for the Suns: OLD: OFILES = $(O_COMPLEX) $(O_GENERIC) $(O_NEW) \ $(O_STATIC) $(O_STREAM) $(O_TASK) NEW: OFILES = $(O_COMPLEX) $(O_GENERIC) $(O_NEW) \ $(O_STATIC) $(O_STREAM) OLD: libC.a: $(O_COMPLEX) $(O_GENERIC) $(O_NEW) $(O_STATIC) $(O_STREAM) Task NEW: libC.a: $(O_COMPLEX) $(O_GENERIC) $(O_NEW) $(O_STATIC) $(O_STREAM) The problem was that the shell code executed in the 'Task' target was failing for some reason, and causing make to die. Since the task library is not supported on Suns anyway, there is no loss from doing this. D) Testing Getting cfront to recompile itself is certainly a good test. The only other test I have come up with is this progam: #include <stream.h> main() { cout << "Hello, world\n"; } What makes this worth doing is that 'cout' has a static constructor; thus, if the 'munch' program does not work properly, said constructor will not be initialized and when the program is run you will probably get a core dump (dies in __ostream__lshiftFPC__) instead of 'Hello, world'. E) From the author The following comments were sent to me by Bjarne as I was trying to get C++ up ; there is some overlap with the above but they may be more comprehensible than mine. > I will brifly explain the porting process here. Cfront is a compiler front-end, > not a simple pre-processor, in particular it has to know about the target machine > in order to calculate sizeofs. What you get on the tape is a C version for a VAX > or a 3B. To run cfront on a different machine you must port, not merely re-compile. > > When you port, the key step is to create a new set of C source files like the ones > you received for a VAX. This you do by compiling the C++ source files using > > (1) header files <stdio.h> and <ctype.h> from the target machine (using > the -I directive) so that the system dependencies are hanled correctly. > (2) a size/align file for the target machine (using the +x directive) so > that cfront agrees with the target machine as to the sizes of objects. > > (here is the source of your problem with expr..c - the sizes has been > calculated wrongly using VAX sizes on a SUN and the free store is > messed up). > > Here is a size/align file for a Sun: [ Given above ] > Assuming you call it ``szal'' and put it in directory SUN (where I have also > assumed that stdio.h and ctype.h is stored) you can make a ..c file like this: > > CC -F -ISUN +xSUN/szal main.c | sed /^#/d > main..c > > Don't worry about SZ_TOP and AL_TOP, they are not really used. > > With that done you can simply compile and install munch.c and the libraries on > the terget machine using the new cfront. > > This is of course not as easy as porting a simple machine independent C program, > but not too bad for a compile port. Think of CC as a two pass compiler using a > particularly readable and portable intermediate form (seen this way cc is the > fabled ``machine independent assembler'' or ``universal intermediate form'' - > UNCOL). > > - Bjarne Jon Leech (jon@csvax.caltech.edu || ...seismo!cit-vax!jon) Caltech Computer Science Graphics Group __@/
olson@batcomputer.TN.CORNELL.EDU (Todd Olson) (03/24/86)
In article <952@megaron.UUCP> whm@megaron.UUCP writes: >I just installed C++ on our 4.3bsd VAXs and it didn't go too smoothly. Yes, indeed. I've been thinking about posting a similar article about the problems of bring C++ under bsd4.2 and asking for assistance. I have experienced every problem you have, and since I'm not too experienced in bring things up I have been stumbling all over the place. Maybe some of the wiser 4.2 types with interest in C++ could be pursuaded to make available a better make file (maybe it could go on the distribution tape) (I guess I have been spoiled by all the fine work the UW people did in making TeX available for bsd4.*) Thanks for your note, it will help me. If I ever get my C++ up I'll post my experiences Todd Olson ARPA: olson@lasspvax -- or -- olson%lasspvax.tn.cornell.edu@cu-arpa UUCP: {ihnp4,allegra,...}!cornell!lasspvax!olson US Mail: Dept Physics, Clark Hall, Cornell University, Ithaca, New York 14853-2501 -- Todd Olson ARPA: olson@lasspvax -- or -- olson%lasspvax.tn.cornell.edu@cu-arpa UUCP: {ihnp4,allegra,...}!cornell!lasspvax!olson US Mail: Dept Physics, Clark Hall, Cornell University, Ithaca, New York 14853-2501
mat@mtx5a.UUCP (m.terribile) (04/03/86)
> WARNING: The following is a LONG (~440 lines) message about > problems and experiences porting C++. Hit 'n' now unless you are > having problems getting the new release of C++ running. . . . > B) Optimization > > On UTS, the optimizer pass of the C compiler (/lib/c2) core > dumps while trying to compile parts of the C++ library > (specifically lib/complex/io.c). Rather than try to figure out > why, I just removed the -O flag from 'lib/mk/makefile' and > 'makefile'. Bjarne says that many optimizers break on > automagically generated C code such as that produced by cfront. I can understand why compilers might have difficulty. On the other hand, it is precisely on automagically generated code that optimization is most needed, because such code is most likely to have extra copy and conversion operations introduced by the crypto-automagicalator (eg. cfront :-) Those of us who are in a postion to influence such things should push for robust compilers and optimizers; Maytags, if you will, that can take lots of use and come up for more. > Getting cfront to recompile itself is certainly a good test. > > The only other test I have come up with is this progam: > > #include <stream.h> > main() { > cout << "Hello, world\n"; > } > > What makes this worth doing is that 'cout' has a static > constructor; thus, if the 'munch' program does not work properly, > said constructor will not be initialized and when the program is > run you will probably get a core dump (dies in > __ostream__lshiftFPC__) instead of 'Hello, world'. Ah, yes. For those of you who have the ``patch'' version instead of the ``munch'' version, if this error occurs, check the symbols in the source code for ``patch''. You may find that your cc puts in more or fewer underscores than patch expects. There are two or three lines that need to be changed, and the code is surprisingly simple. I have the patch version up here, and it seems to run fine. -- from Mole End Mark Terribile (scrape .. dig ) mtx5b!mat (Please mail to mtx5b!mat, NOT mtx5a! mat, or to mtx5a!mtx5b!mat) ,.. .,, ,,, ..,***_*.