From: John R. C. <jo...@we...> - 2006-12-28 16:52:38
|
I am converting a batch of programs from a Microfocus for Unix system to TinyCobol (Linux) and am having trouble with subprogram linkages. Here is the situation: In main program "general" I have calls to subprogram maps03 in the form: CALL "maps03" USING MAPS03-WS. This is a WORKING STORAGE copybook with the contents 310 61 [00]: 000000 COPY "wsmaps03.cob". 311 1 [01]: 774001********** 312 2 [01]: 774002* MAPS03 * 313 3 [01]: 774003********** 314 4 [01]: 774004 315 5 [01]: 774005 01 MAPS03-WS. 316 6 [01]: 774006 03 U-DATE PIC x(10). 317 7 [01]: 774007 03 FILLER REDEFINES U-DATE. 318 8 [01]: 774008 05 U-DAYS PIC 99. 319 9 [01]: 774009 05 FILLER PIC X. 320 10 [01]: 774010 05 U-MONTH PIC 99. 321 11 [01]: 774011 05 FILLER PIC X. 322 12 [01]: 05 u-cc pic 99. 323 13 [01]: 774012 05 U-YEAR PIC 99. 324 14 [01]: 774013 03 U-BIN PIC 9(8) comp. The subprogram contains the line: PROCEDURE DIVISION USING MAPA03-WS. and in the linkage section: 000860 LINKAGE SECTION. 73 73 [00]: 000870*--------------- 74 74 [00]: 000880* 75 75 [00]: 000890********** 76 76 [00]: 000900* MAPS03 * 77 77 [00]: 000910********** 78 78 [00]: 000920 79 79 [00]: 000930 01 MAPA03-WS. 80 80 [00]: 000940 03 A-DATE PIC X(10). 81 81 [00]: 000950 03 FILLER REDEFINES A-DATE. 82 82 [00]: 000960 05 A-DAYS PIC 99. 83 83 [00]: 000970 05 FILLER PIC X. 84 84 [00]: 000980 05 A-MONTH PIC 99. 85 85 [00]: 000990 05 FILLER PIC X. 86 86 [00]: 05 A-CC pic 99. 87 87 [00]: 001000 05 A-YEAR PIC 99. 88 88 [00]: 001010 03 A-BIN PIC 9(8) comp. Let's assume static linkage (simpler?) and Legacy layout 1. What options should I have on the compile of maps03.cbl? 2. What options should I have on the compile of general.cbl? Currently when compiled general.cbl can't find subprogram maps03 which was compiled with the -a option. I also compiled it with the -c option. All are in the same directory. The assembler pass says: general.o(.text+0x3dc): In function `general': : undefined reference to `maps03' John Culleton |
From: David E. <de...@us...> - 2006-12-29 07:42:08
|
John R. Culleton wrote: > I am converting a batch of programs from a Microfocus > for Unix system to TinyCobol (Linux) and am having > trouble with subprogram linkages. > Here is the situation: > > In main program "general" I have calls to subprogram > maps03 in the form: > CALL "maps03" USING MAPS03-WS. > ... > The subprogram contains the line: > ... > PROCEDURE DIVISION USING MAPA03-WS. > ... > Let's assume static linkage (simpler?) and Legacy > layout > > 1. What options should I have on the compile of maps03.cbl? > > 2. What options should I have on the compile of general.cbl? It really not difficult, once you understand some basics. First of all COBOL, unlike other languages such as C, does not have a default entry point. Meaning the first program (function) to be executed withing the binary. TC will try to determine which is a main-program, and which are sub-programs. It does so by using the 'STOP RUN', for main, and 'EXIT PROGRAM', for sub-programs. Once TC detects a main-program, it will automatically generate a entry point 'main', and the code to call the COBOL main-program. Since this method does not work 100% of the time, you can override this behaviour using the command line, or resourse file options. Then it will up to the programmer to define the entry point. Note that TC version 0.63, does not allow the use of '-' (dash) in a program name (PROGRAM-ID). This is due to a x86 assembler limitation. Finally, the type of COBOL CALL will determine which type of linkage used. If you use CALL 'literal', then compile time linkage is used. If you use CALL identifier, then run-time linkage is used. Meaning that the TC run-time library will try to find and load the library containing the sub-program. Note that run-time linkage works well on UN*X (ELF), but not so well on Win32 (PE-COFF). > Currently when compiled general.cbl can't find subprogram > maps03 which was compiled with the -a option. > I also compiled it with the -c option. > All are in the same directory. > The assembler pass says: > general.o(.text+0x3dc): In function `general': > : undefined reference to `maps03' Actually that is a linker error. As per you example above, you could use the following: htcobol -c general.cbl htcobol -c maps03.cbl gcc -o what-ever general.o maps03.o -L ... Or if you have a library of routines, you could use the following: htcobol -c sub01.cbl ... htcobol -c subNN.cbl ar cr libsubs.a sub01.o ... subNN.o ranlib libsubs.a gcc -o what-ever general.o -L... -lsubs ... There are some examples in the 'test.code/t07' and 'test.code/t15' directories. Or if you would like some advanced examples see the 'test.code/t33' and 'cobrun/test.code' directories. Hope this helps. |
From: John R. C. <jo...@we...> - 2006-12-29 14:36:41
|
On Friday 29 December 2006 02:40, David Essex wrote: > John R. Culleton wrote: > > I am converting a batch of programs from a Microfocus > > for Unix system to TinyCobol (Linux) and am having > > trouble with subprogram linkages. > > Here is the situation: > > > > In main program "general" I have calls to subprogram > > maps03 in the form: > > CALL "maps03" USING MAPS03-WS. > > ... > > The subprogram contains the line: > > ... > > PROCEDURE DIVISION USING MAPA03-WS. > > ... > > Let's assume static linkage (simpler?) and Legacy > > layout > > > > 1. What options should I have on the compile of maps03.cbl? > > > > 2. What options should I have on the compile of general.cbl? > > It really not difficult, once you understand some basics. > > First of all COBOL, unlike other languages such as C, does not have a > default entry point. Meaning the first program (function) to be executed > withing the binary. > > TC will try to determine which is a main-program, and which are > sub-programs. It does so by using the 'STOP RUN', for main, and 'EXIT > PROGRAM', for sub-programs. > Once TC detects a main-program, it will automatically generate a entry > point 'main', and the code to call the COBOL main-program. > > Since this method does not work 100% of the time, you can override this > behaviour using the command line, or resourse file options. Then it will > up to the programmer to define the entry point. > > Note that TC version 0.63, does not allow the use of '-' (dash) in a > program name (PROGRAM-ID). This is due to a x86 assembler limitation. > > Finally, the type of COBOL CALL will determine which type of linkage used. > If you use CALL 'literal', then compile time linkage is used. > If you use CALL identifier, then run-time linkage is used. Meaning that > the TC run-time library will try to find and load the library containing > the sub-program. > > Note that run-time linkage works well on UN*X (ELF), but not so well on > Win32 (PE-COFF). > > > Currently when compiled general.cbl can't find subprogram > > maps03 which was compiled with the -a option. > > I also compiled it with the -c option. > > All are in the same directory. > > The assembler pass says: > > > > general.o(.text+0x3dc): In function `general': > > : undefined reference to `maps03' > > Actually that is a linker error. > > As per you example above, you could use the following: > > htcobol -c general.cbl > htcobol -c maps03.cbl > gcc -o what-ever general.o maps03.o -L ... > > Or if you have a library of routines, you could use the following: > > htcobol -c sub01.cbl > ... > htcobol -c subNN.cbl > ar cr libsubs.a sub01.o ... subNN.o > ranlib libsubs.a > > gcc -o what-ever general.o -L... -lsubs ... > > > There are some examples in the 'test.code/t07' and 'test.code/t15' > directories. > Or if you would like some advanced examples see the 'test.code/t33' and > 'cobrun/test.code' directories. > > > Hope this helps. > > > Thanks much. My next question was going to be: "Which examples in test.code show linkages to subprograms?" But you answered it ahead of time. The Tiny-Cobol manual remains unfinished, which is a pity. I'll substitute your message above for the missing piece. -- John Culleton Able Indexing and Typesetting Precision typesetting (tm) at reasonable cost. Satisfaction guaranteed. http://wexfordpress.com |
From: John R. C. <jo...@we...> - 2006-12-29 19:38:30
|
On Friday 29 December 2006 02:40, David Essex wrote: > John R. Culleton wrote: > > I am converting a batch of programs from a Microfocus > > for Unix system to TinyCobol (Linux) and am having > > trouble with subprogram linkages. > As per you example above, you could use the following: > > htcobol -c general.cbl > htcobol -c maps03.cbl > gcc -o what-ever general.o maps03.o -L ... > That didn't work so I built two toys and compiled/linked them thus: htcobol -F -c testmain.cbl htcobol -F -c testcalled.cbl gcc -o testprog testmain.o testcalled.o ------------------------------------------------------------ On the gcc step I got multiple errors, such as: ..... testcalled.o(.text+0x92): In function `TESTCALLED': : undefined reference to `tcob_move' testcalled.o(.text+0xb7): In function `TESTCALLED': : undefined reference to `tcob_stop_run' Here is the source of the calling program: 000010 IDENTIFICATION DIVISION. 000020 PROGRAM-ID. TESTMAIN. 000070 ENVIRONMENT DIVISION. 000080 000090 CONFIGURATION SECTION. 000100 SOURCE-COMPUTER. 000110 Linux. 000120 OBJECT-COMPUTER. 000230 Linux. 000140 000150 INPUT-OUTPUT SECTION. 000160 FILE-CONTROL. 000170 SELECT PRINTFILE ASSIGN TO PRINTER. 000180 DATA DIVISION. 000190 000200 FILE SECTION. 000210 000220 WORKING-STORAGE SECTION. 000230 01 TESTSTRING PIC X(80). 000240 PROCEDURE DIVISION. 000250 001-MAIN-PROCEDURE. 000260 DISPLAY "testmain". CALL "TESTCALLED" USING TESTSTRING. DISPLAY TESTSTRING. 000270 STOP RUN. ---------------------------------------------------- ...and here is the called program: 000010 IDENTIFICATION DIVISION. 000020 PROGRAM-ID. TESTCALLED. 000070 ENVIRONMENT DIVISION. 000080 000090 CONFIGURATION SECTION. 000100 SOURCE-COMPUTER. 000110 Linux. 000120 OBJECT-COMPUTER. 000230 Linux. 002014 DATA DIVISION. 000150 LINKAGE SECTION. 000230 01 TESTIT PIC X(80). 000240 PROCEDURE DIVISION USING TESTIT. 000250 001-MAIN-PROCEDURE. 000260 DISPLAY "testcalled". MOVE "made it!" to TESTIT. EXIT PROGRAM. ------------------------------------------------------- I think I am missing a library call somewhere. Which library and on which compile command string? Or is it something else? Thanks again for all the help. -- John Culleton Able Indexing and Typesetting Precision typesetting (tm) at reasonable cost. Satisfaction guaranteed. http://wexfordpress.com |
From: David E. <de...@us...> - 2006-12-29 23:25:51
|
John R. Culleton wrote: > ... > That didn't work so I built two toys and compiled/linked them thus: > > htcobol -F -c testmain.cbl > htcobol -F -c testcalled.cbl > gcc -o testprog testmain.o testcalled.o > > On the gcc step I got multiple errors, such as: > ..... > testcalled.o(.text+0x92): In function `TESTCALLED': > : undefined reference to `tcob_move' > testcalled.o(.text+0xb7): In function `TESTCALLED': > : undefined reference to `tcob_stop_run' > ... > I think I am missing a library call somewhere. > Which library and on which compile command string? > Or is it something else? You neglected to add the libraries for the link step. Normally TC (htcobol) will add the libraries to the linkage, as shown below. If however you choose to use GCC directly, you have to add the libraries for the link step. $make htcobol -c -P -I../copybooks -I. test03.cob gcc -o test03 test03.o -L/usr/local/lib -lhtcobol -ldb1 -lm -ldl $htcobol -v -test03.cob as -o test03.o test03.s gcc -o test03 test03.o -L/usr/local/lib -lhtcobol -ldb1 -ldl -lm $make -n test15 htcobol -c -P -I../copybooks -I. test15.cob htcobol -c -P -I../copybooks -I. test15a.cob gcc -I/usr/local/include -o test15b.o -c test15b.c gcc -o test15 test15.o test15a.o test15b.o \ -L/usr/local/lib -lhtcobol -ldb -ldl -lm Hint: If you prefer to use a specific format (fixed or free) for your source files, change the default to that format in the TC resource file (htcobolrc). # Specify COBOL program default input format # free format -> PGM_FORMAT_FREE # fixed format -> PGM_FORMAT_FIXED # (compiler default=free format) #PGM_FORMAT_FREE PGM_FORMAT_FIXED If you are working with libraries, same youself some work by using make files. Hope this helps. |
From: John R. C. <jo...@we...> - 2006-12-30 13:47:15
|
On Friday 29 December 2006 18:24, David Essex wrote: > # Specify COBOL program default input format > # free format -> PGM_FORMAT_FREE > # fixed format -> PGM_FORMAT_FIXED > # (compiler default=free format) > #PGM_FORMAT_FREE > PGM_FORMAT_FIXED > I fixed this in one htcobolrc but the system is finding another. So I will change all of them. > If you are working with libraries, same youself some work by using make > files. > A script also helps such as: htcobol -c -P -F -I../copybooks -I. testmain.cbl htcobol -c -P -F -I../copybooks -I. testcalled.cbl gcc -o testprog testmain.o \ testcalled.o -L/usr/local/lib -lhtcobol -ldb -ldl -lm I will generalize this to take different filenames using $1, $2 etc. > Hope this helps. > It surely does. Thanks for your patience. John Culleton |
From: David E. <de...@us...> - 2006-12-30 20:15:26
|
John R. Culleton wrote: > I fixed this in one htcobolrc but the system is > finding another. So I will change all of them. You can check which one TC is using the following commands. $env | grep 'TCOB_' TCOB_OPTIONS_PATH=/usr/local/share/htcobol TCOB_RTCONFIG_PATH=/usr/local/share/htcobol >> If you are working with libraries, same youself >> some work by using make files. > > A script also helps such as: > htcobol -c -P -F -I../copybooks -I. testmain.cbl > htcobol -c -P -F -I../copybooks -I. testcalled.cbl > gcc -o testprog testmain.o \ > testcalled.o -L/usr/local/lib -lhtcobol -ldb -ldl -lm > > I will generalize this to take different filenames > using $1, $2 etc. Yes, that will work. However make files will do a lot of the work for you, once setup. They really are indispensable for projects with more than one or two sources. For example if you have one sub-program which is used (statically linked) in 5 modules (programs). If you change that sub-program you have find and rebuild all of the modules. Make can detect the change and re-compile and link the dependencies where necessary. A trivial example can be found in 'test.code/t15'. $make test15 htcobol -c -P -I../copybooks -I. test15.cob htcobol -c -P -I../copybooks -I. test15a.cob gcc -I/usr/local/include -o test15b.o -c test15b.c gcc -o test15 test15.o test15a.o test15b.o \ -L/usr/local/lib -lhtcobol -ldb1 -ldl -lm $touch test15a.cob $make test15 htcobol -c -P -I../copybooks -I. test15a.cob gcc -o test15 test15.o test15a.o test15b.o \ -L/usr/local/lib -lhtcobol -ldb1 -ldl -lm Hint: If you plan to use make files for COBOL projects, copy the 'test.code/config/COB.rules.in' file to 'config' directory (/usr/local/config ?). Adding the following lines to the make file will enable make to build objects from files with COBOL suffixes. COB=htcobol COPYBOOKS= -I../copybooks COBFLAGS=-P ${COPYBOOKS} ... include ${prefix}/config/COB.rules.in # contents of 'COB.rules.in' # Rules for compiling COBOL sources .SUFFIX: .cob .cbl .o %.o: %.cob $(COB) -c $(COBFLAGS) $< # $(COB) $(COBFLAGS) $< %.o: %.cbl $(COB) -c $(COBFLAGS) $< # $(COB) $(COBFLAGS) $< Hope this helps. |
From: John R. C. <jo...@we...> - 2006-12-30 20:28:46
|
On Saturday 30 December 2006 15:13, David Essex wrote: > John R. Culleton wrote: > > I fixed this in one htcobolrc but the system is > > finding another. So I will change all of them. > > You can check which one TC is using the following commands. > > $env | grep 'TCOB_' > TCOB_OPTIONS_PATH=/usr/local/share/htcobol > TCOB_RTCONFIG_PATH=/usr/local/share/htcobol It doesn't seem to be using any of them. Do I need a statement in my /etc/profile per the above? -- John Culleton Able Indexing and Typesetting Precision typesetting (tm) at reasonable cost. Satisfaction guaranteed. http://wexfordpress.com |
From: David E. <de...@us...> - 2006-12-31 00:05:26
|
John R. Culleton wrote: > David Essex wrote: > ... >> You can check which one TC is using the following commands. >> >> $env | grep 'TCOB_' >> TCOB_OPTIONS_PATH=/usr/local/share/htcobol >> TCOB_RTCONFIG_PATH=/usr/local/share/htcobol > > It doesn't seem to be using any of them. > Do I need a statement in my /etc/profile per the above? At compile-time TC (htcobol) will try find the compile-time resource file 'htcobolrc'. At run-time the TC RTL will load the run-time resource file 'htrtconf'. The search sequence is as follows: 1) Use the environment variables TCOB_OPTIONS_PATH and TCOB_RTCONFIG_PATH, and if the files exist load those files. 2) If the environment variables are not defined, or the resource files are not found in that path, use the a default path set at TC configure in the file 'htconfig.h'. 3) If the above two methods fail to locate and load the files, use the internal defaults set when TC is configured. This method will print a warning, as follows. $htcobol -V Cobol parameter file '/usr/local/share/htcobol/htcobolrc' not found - using configure defaults ... The advantage of using environment variables is that you can have multiple resource files. For example you can have a global (i.e. /etc/profile) and local (i.e. $HOME/.profile or .bashrc) definitions. The TC install process will not automatically add these 'TCOB_*' environment variables to the any of the profile files. How to add these environment variables. Bash example: export TCOB_OPTIONS_PATH=/usr/local/share/htcobol export TCOB_RTCONFIG_PATH=/usr/local/share/htcobol In your case, TC is most likely using a path defined when the sources were configured. The problem with this approach is that, currently, there is no way to echo this path. So it could be an old file. Actually, there is one way to find the current resource path. Temporarily move the resource directory, and then issue a 'htcobol' version command and see if it prints a warning, as above. example: $mv -i /usr/local/share/htcobol /usr/local/share/htcobol0 $htcobol -V ... But to answer your question, do you need them NO. Should I use them, YES. Hope this helps. |