No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
- Answered by: drs66
Please leave any comments here within the
next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !
Nic;o)
Main Topics
Browse All Topics





by: drs66Posted on 2002-08-07 at 12:02:18ID: 7206839
this article may help,
---------
-----
------
1.5/precom p/admin/pc scfg.cfg
c fun2.c
/shared/li bsqr.a \ /shared/li bdis.a
------
/shared/li ballsh.so
----
8.1.5/lib/ -lclntsh
8.1.5/lib/ -lclient8 1.5/lib/li bsql8.a 1.5/lib/sc orept.o 1.5/lib/ss coreed.o 1.5/rdbms/ lib/kpudfo .o 1.5/lib/ld flags` 1.5/lib/ld flags` 1.5/lib/ld flags` 1.5/lib/ld flags` 1.5/lib/li bpls8.a 1.5/lib/li bplp8.a 1.5/lib/li bpls8.a 1.5/lib/sy sliblist`
t t/u04/orac le/Very24/ lib/__fstd .o /SUNWspro/ lib:/usr/o penwin/lib :/opt/cobo l/coblib: /SUNWclust er/lib:/us r/ccs/lib: /usr/lib -Qy .o ab.o
8.1.5/lib -lclntsh
lic #To include sqlca and other headers
lic #To include sqlca and other headers
lic #To include sqlca and other headers sh.so rt/malshou s/liballsh .so
lic #To include sqlca and other headers oduct/8.1. 5/lib rt/alatasi /shared
---------- ---------- ---------- ---------- ---------- ----
good luck,
daniels@asix.com
Bookmark Fixed font Go to End
Doc ID: Note:61628.1
Subject: 8i: Building Makefiles and Libraries for Oracle Precompilers
Type: BULLETIN
Status: PUBLISHED
Content Type: TEXT/PLAIN
Creation Date: 17-DEC-1996
Last Revision Date: 27-NOV-2001
8i: Building Makefiles and Libraries for the Oracle Precompilers
This article covers the following important concepts that programmers need to
understand when developing 3GL programs on UNIX platforms:
1. What is the makefile?
2. What are symbols and libraries?
3. What is the difference between static and shared libraries?
4. How to create the Oracle shared library
5. How to create your static libraries
6. How to create your shared libraries
7. How to create your own customized makefile to compile and
link Oracle precompiler programs
8. Common issues
1. What is the Makefile?
-------------------------
A makefile is a description file used by the UNIX 'make' utility. The
makefile includes dependencies and rules for building a target executable.
Such rules can be precompiling commands, compiling commands, linking commands,
or commands for removing temporary files. The ultimate goal of the make
utility is to build the final executable program using the rules contained
within the makefile. The makefile can have any name.
2. What are Symbols and Libraries?
--------------------------
When you create a 3GL program, you have external references, global and local
functions, and static and global variables. After compiling and producing the
object file, you would have external, global, and local symbols. The linker
assigns addresses to these variable and function symbols. Therefore, the
symbols become names for memory addresses and are derived from the named
functions.
Object files are created when you compile your function source files. These
functions can be linked with a main program to produce an executable, or
bundled into one archived file called a library. So, the library becomes a
repository for these object files referencing the defined symbols.
3. Static vs. Shared Libraries
--------------------------
Static libraries have an extension .a which means the library is archived using the
UNIX 'ar' utility. When linking with a static library, a physical copy of the
library is attached to the executable program. That is, the object files and
the libraries are linked together before calling the executable. This makes
your executable size fairly large and may present resource (disk or memory)
concerns.
With a shared library, on the other hand, the library is sharable among many
versions of different executable files. The entire copy of the library
is not attached to the executable. Think of it as a pointer from the
executable to the shared library.
The shared library is dynamically linked to an executable at run time. The
shared or dynamic link has advantages over the static link. The size of the
code to be executed can be considerably smaller. You may gain memory
efficiency if many applications are to be run at the same time, and one copy
of the shared library is used by all of them.
4. Oracle Shared Library
-------------------------
In Oracle V7.1 and earlier versions, all Oracle libraries were static which
caused user-created applications to be very large. This was because all of
the Oracle libraries were attached to the executable.
Oracle first created a shared library for applications libraries in Oracle
V7.2. Now, the Oracle runtime libraries for Precompilers, Oracle Call
Interface (OCI), and Transaction Monitor (XA) are bundled into one shared
library called libclntsh. Oracle, however, kept the static libraries in case
you do not want to link shared.
Note: OCI static libraries are in libclient.a beginning with Oracle V7.3.
libclntsh may take extension .so, .a or .sl, depending on the
platform.
Even though Oracle creates the shared library during the installation,
you may need to create it again if it was missed, or if you want to
have another copy of it. Oracle provides a makefile called ins_rdbms.mk
that you use to create libclntsh.
% cd $ORACLE_HOME/rdbms/lib
% make -f ins_rdbms.mk client_sharedlib
If you wish to link your Pro*C or OCI program with the shared or static
libraries, perform the following steps:
a. Create libclntsh using ins_rdbms.mk.
b. Set the environment variable LD_LIBRARY_PATH to $ORACLE_HOME/lib
Note: Platforms such as HP-UX recognize SHLIB_PATH instead for dynamic
linking. Consult your UNIX documentation for further detail.
Using the demo_proc.mk file, the rules for building your Pro*C targets are:
-- Shared linking
build: $(OBJS)
$(CC) -o $(EXE) $(OBJS) -L$(LIBHOME) $(PROLDLIBS)
-- Static linking
build_static: $(OBJS)
$(CC) -o $(EXE) $(OBJS) -L$(LIBHOME) $(STATICPROLDLIBS)
Using the demo_rdbms.mk file, the rules for building your OCI targets are:
-- Shared linking
build: $(LIBCLNTSH) $(OBJS)
$(ECHODO) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) $(OCISHAREDLIBS)
-- Dynamic linking
build_static: $(OBJS)
$(ECHODO) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) $(SSDBED) $(DEF_ON) \
$(OCISTATICLIBS)
Note: Due to platform and Oracle version variations, the targets and
makefiles themselves may appear slightly different from platform
to platform. This article should be used as a GUIDELINE only.
5. Creating Your Static Library
--------------------------
To address portability and reusability concerns, you may want to create
libraries with your object files. Your libraries can be common Pro*C or C
functions used by different applications. These libraries can be added
to the link line of your Pro*C application.
The following are four basic Pro*C functions:
connect() - establishes the connection to the database
sqr() - inserts into the table scott_tab
disconnect() - closes the connection to Oracle
sql_err() - prints any Oracle error codes that occur in the application
These functions are stored in files fun2.pc, fun3.pc, fun1.pc, and fun4.pc,
respectively.
/* fun2.pc */
#include <stdio.h>
#include "sqlca.h"
void connect()
{
char *userid="scott/tiger";
exec sql whenever SQLERROR do sql_err();
exec sql connect :userid;
printf("\n Connected To Scott\n");
sqr();
}
/* fun3.pc */
#include "sqlca.h"
void sqr()
{
int * sum, n, j;
printf("\nHow many numbers do you wish to square? ");
scanf(" %d",&n);
sum= (int *)malloc(n*sizeof(int));
for(j=0; j<=n-1; j++)
{
printf("\nEnter %d number", j+1);
scanf("%d", &sum[j]);
}
for(j=0; j<=n-1; j++)
{
exec sql insert into scott_tab values (:sum[j],:sum[j] * :sum[j]);
}
}
/* fun1.pc */
#include "sqlca.h"
void disconnect()
{
exec sql whenever sqlerror do sql_err();
exec sql commit work release;
}
/* fun4.pc */
#include "sqlca.h"
void sql_err()
{
printf("Error %d", sqlca.sqlcode);
exit(1);
}
First precompile and compile the functions to generate the object files in
two separate steps.
%proc iname=fun2.pc
Pro*C/C++: Release 8.1.5.0.0 - Production on Tue Feb 1 10:13:40 2000
(c) Copyright 1999 Oracle Corporation. All rights reserved.
System default option values taken from: /u05/app/oracle/product/8.
%cc -c -I $ORACLE_HOME/precomp/publi
Precompiling and compiling fun3.pc, fun1.pc, and fun4.pc similarly you get
their three object files as well.
It is possible for one static library to contain all four functions, but here
you create two archived static libraries:
ar r libsqr.a fun2.o fun3.o
ar r libdis.a fun1.o fun4.o
Note, on some platforms, the linker does not automatically create the lookup
table. You may need to run the following additional command 'ranlib libsqr.a'.
Consult your UNIX manual for additional information about the 'ar' and 'ranlib'
utilities. This additional step is not needed for Solaris 2.6.
Now, you can call connect() and the three other functions outlined above,
provided you add libsqr.a and libdis.a to the link line. The following is a
simple calling Pro*C program, test.pc that references the functions that
you created.
#include "sqlca.h"
main()
{
exec sql whenever SQLERROR do sql_err();
printf("\n Welcome\n");
connect();
disconnect();
printf("\n GoodBye\n");
}
Before executing test.pc, you need to link libsqr.a, and libdis.a. If you
are using the Oracle provided makefile, demo_proc.mk, simply create a
MYSTATLIB macro and add modify the link line as:
MYSTATLIB= /u01/home/usupport/alatasi
/u01/home/usupport/alatasi
build_static: $(OBJS)
$(CC) -o $(EXE) $(OBJS) $(MYSTATLIB) -L$(LIBHOME) $(STATICPROLDLIBS)
Note: The build_static target distributed with version 8.1.5 requires
modifications to the STATICPROLDLIBS AND PROLDLIBS macros.
6. Creating Your Shared Library
--------------------------
As with creating static libraries, creating shared libraries may differ
slightly from one platform to another. The following is how a shared library
is created for fun1.o, fun2.o, fun3.o, and fun4.o on a Solaris 2.6 machine:
ld -G -o liballsh.so fun1.o fun2.o fun3.o fun4.o
Note, the static and shared libraries are created from the system prompt.
You could, however, include the linker command in your makefile or in a shell
script.
Now that you have created the shared library, add it to the link line in your
makefile. If you are using demo_proc.mk, add liballsh.so to the 'build' target
the same way you added the libsqr and libdis libraries. In your makefile,
create a macro for liballsh.so and call it MYSHARLIB.
MYSHARLIB= /u01/home/usupport/alatasi
build: $(OBJS)
$(CC) -o $(EXE) $(OBJS) $(MYSHARLIB) -L$(LIBHOME) $(PROLDLIBS)
7. Creating Your Own Makefile
--------------------------
Oracle makefiles are multi-purpose. In addition to precompiling, compiling,
and linking your applications, there are makefiles used for product
installation (Pro*C, Pro*COBOL, and libclntsh). Oracle asks customers to use
the Oracle-provided makefiles because they are fully supported. If customers
need to add their own files or libraries, they can modify the Oracle provided
makefiles as outlined in the prior section.
A Customized Makefile
---------------------
This section contains an easy method to create a customized makefile. Since
understanding the components of the UNIX 'make' utility is not the primary
purpose of this bulletin, we assume that the reader has some familiarity with
'make'. We refer to the Pro*C makefile, demo_proc.mk, to build our makefile.
The intent is to offer a model for producing a customized makefile, based off
the Oracle provided makefiles, for educational purposes only. CUSTOMIZED
MAKEFILES ARE NOT SUPPORTED BY ORACLE SUPPORT SERVICES.
The first step is to build the target for your executables. Looking at
demo_proc.mk, we see that the target 'build' is the one used to create any
dynamically linked executable file. The dependency line contains the macro OBJS
that lists the object files. OBJS and EXE can be specified on the UNIX command
line. The make command line should have at least the CC and LDFLAGS macros.
So, your makefile may start with:
build: $(OBJS)
$(ECHO) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS)
You still need to add the Oracle libraries on your CC line so that they
are linked to the OBJS file to produce the executable file (EXE).
One easy way is to compile an Oracle-provided Pro*C sample program and
save the output to a shell file:
make - f demo_proc.mk build EXE=sample1 OBJS=sample1.o > myshell.sh
When compiling sample1.pc on a Solaris machine, you will note the shared
library, libclntsh.so, being linked:
cc -o sample1 sample1.o -L/u05/app/oracle/product/
Parsing this output file further reveals the static libraries and object
files required for static linking. But remember, you can easily use the
build_static target mentioned earlier to accomplish static linking.
make -f demo_proc.mk build EXE=sample1 OBJS=sample1.o
cc -o sample1 sample1.o
-L/u05/app/oracle/product/
/u05/app/oracle/product/8.
/u05/app/oracle/product/8.
/u05/app/oracle/product/8.
/u05/app/oracle/product/8.
`cat /u05/app/oracle/product/8.
-ln8 -lnl8 -lnro8
`cat /u05/app/oracle/product/8.
-ln8 -lnl8 -lclient8 -lvsn8 -lcommon8 -lskgxp8 -lgeneric8
`cat /u05/app/oracle/product/8.
-ln8 -lnl8 -lnro8 `cat /u05/app/oracle/product/8.
-ln8 -lnl8 -lclient8 -lvsn8 -lcommon8 -lskgxp8 -lgeneric8
/u05/app/oracle/product/8.
/u05/app/oracle/product/8.
/u05/app/oracle/product/8.
-ltrace8 -lnls8 -lcore8 -lnls8 -lcore8 -lnls8
`cat /u05/app/oracle/product/8.
-lm -lthread
When comparing to Oracle version 7.2.2, notice that the link map looked quite
different. Thus, Oracle recommends using our makefile to insulate you from
library changes in a future release.
make - f proc.mk build OBJS=sample1.o EXE=sample1
ld - dy /u04/oracle/V7224/lib/Croa
/u04/oracle/V7224/lib/cour
-R /opt/SUNWcluster/lib -YP,
/opt/SUNWconn/dni/lib:/opt
/u04/oracle/V7224/lib:/opt
-lc /u04/oracle/V7224/lib/crtn
-L/u04/oracle/V7224/lib -o sample1 sample1.o
-lsql /u04/oracle/V7224/lib/osnt
-lsqlnet -lora -lsqlnet -lora -lpls -lnlsrtl3 -lc3v6 -lcore3 -lnlsrtl3 -lcore3
-lsocket -lnsl -lm -ldl -laio -lposix4 -lsocket -lnsl -lm -ldl -laio -lposix4
Now you can copy the Oracle shared library that the linker used to produce the
executable into our makefile:
build: $(OBJS)
$(ECHO) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) \
-L/u05/app/oracle/product/
Pay attention to the command lines within the makefile. If lines continue,
add a backslash (\) to the end of the first line and start the next line with
a tab.
Adding INCLUDE, CFLAGS, and CC macros to our makefile results in a complete
makefile that compiles and links any Pro*C program if user-defined files or
libraries are not needed.
INCLUDE= $(ORACLE_HOME)/precomp/pub
CFLAGS= -I$(INCLUDE)
CC=cc
If you precompile your Pro*C program separately as:
proc iname=test.pc
you can call our makefile to create the executable:
make -f ourmake.mk EXE=test OBJS=test.o
Note that the LD_LIBRARY_PATH environment variable should contain the path
to the Oracle libraries-- $ORACLE_HOME/lib. Otherwise, you must specify this
path using the linking macro (LDFLAGS) or specify the full path of the Oracle
libraries on the CC line.
To complete the basic components of the makefile, add the Pro*C precompiler.
Since the 'build' target depends on OBJS which has no prerequisites or rules,
a suffix rule is used here to cause the make utility to invoke the C compiler
to create the object files. After including the Pro*C precompiler and the
suffix rule, our makefile constitutes a complete makefile which precompiles,
compiles, and links any Pro*C program with Oracle shared libraries.
Here it is:
INCLUDE= $(ORACLE_HOME)/precomp/pub
CFLAGS= -I$(INCLUDE)
CC=cc
PROC= $(ORACLE_HOME)/bin/proc
.SUFFIXES: .o .c .pc
.pc.o:
$(PROC) iname=$*.pc
$(CC) $(CFLAGS) -c $*.c
build: $(OBJS)
$(ECHO) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) -lclntsh
make -f ourmake.mk EXE=test OBJS=test.o
For simplicity, we did not use the PROCFLAGS macro to specify the precompiler
options. It can be added to the .pc.o suffix rule. We have so far put
together the basic steps to write a customized makefile. It is very likely
that you will need to organize the file differently and add your own object
files and shared/archived libraries. For instance, the Oracle libraries
might be bundled together under the macro ORACLELIBS, or Oracle
shared and static libraries might be assigned to macros LIBSHR
and LIBSTAT respectively. Your makefile may look like:
INCLUDE= $(ORACLE_HOME)/precomp/pub
CFLAGS= -I$(INCLUDE)
CC=cc
PROC= $(ORACLE_HOME)/bin/proc
ORACLELIBS= $(ORACLE_HOME)/lib/libclnt
MYSHARLIB=/u05/home/tsuppo
.SUFFIXES: .o .c .pc
.pc.o:
$(PROC) iname=$*.pc
$(CC) $(CFLAGS) -c $*.c
build: $(OBJS)
$(ECHO) $(CC) $(LDFLAGS) -o $(EXE) $(MYSHARLIB) $(OBJS) \
$(ORACLELIBS)
The CC line is very clear, and easy to understand and maintain.
As we have mentioned earlier, Oracle gives users an option to
link with shared or static libraries. We can incorporate that into
our makefile. In addition, we can add also the libraries that we
created earlier: libsqr, libdis, and liballsh.
The last thing that should be mentioned before putting out the
last version of our makefile is the linker. How do you include
your library in the link line? The linker searches the following
to find libraries specified on the link line:
- Paths assigned to the LD_LIBRARY_PATH environment variable
- Default paths, e.g. /usr/lib and /lib
- Paths passed by the linking flags -L and -l in the makefile. Ensure
that the LD_LIBRARY_PATH includes these paths.
- Libraries specified with complete paths
We will use the linking flags to specify the path to the libraries that we
have created. We will put these flags in the macro, LDFLAGS, in the
makefile. We will assign two paths to LDFLAGS, one for the Oracle
libraries, and the other for ours.
LDFLAGS=-L$(LIBHOME) -L$(MYLIBHOME)
Now, any library in LIBHOME or MYLIBHOME can be linked using the -l
option. Note, it is very likely that the path to the Oracle
libraries is already assigned to LD_LIBRARY_PATH. Here is the final
version of our makefile:
#This is our makefile
#
INCLUDE= $(ORACLE_HOME)/precomp/pub
CFLAGS= -I$(INCLUDE) -dy
LDFLAGS=-L$(LIBHOME) -L$(MYLIBHOME)
PROC= $(ORACLE_HOME)/bin/proc
LIBHOME=/u05/app/oracle/pr
MYLIBHOME=/u01/home/usuppo
CC=cc
MYSHARLIB= -lallsh
MYSTATLIB= -lsqr -ldis
ORACLELIBS=clntsh
.SUFFIXES: .o .c .pc
.pc.o:
$(PROC) iname=$*.pc
$(CC) $(CFLAGS) -c $*.c
build: $(OBJS)
$(ECHO) $(CC) $(LDFLAGS) -o $(EXE) -l$(MYSHARLIB) $(OBJS) \
-l$(ORACLELIBS)
8. Common Issues
-----------------
Q. I modified the Oracle provided makefile, and now I am getting undefined
symbols at link time.
A. You may be using libraries that are not specified on your link line, or
the library may be misplaced. The simplest way to solve the problem is
to:
1. Use the 'nm' or 'ar' utilities to search for the symbols where your
libraries are located. For example, mysymbol is an undefined symbol:
nm *.a | grep mysymbol
2. Add the library to different places on the CC link line.
3. If you eliminate the undefined symbol error, remove the unnecessary
copies using a trial-and-error approach.
Some of the most common undefined symbol errors are sqlcex or sqlctx.
These symbols are referenced in libsql.a or libclntsh.so. Ensure that
the libsql or libclntsh is linked properly on your link line.
The code in this bulletin was initially developed on a Solaris 2.4 machine
using RDBMS 7.2.2/ProC 2.1.2, and later updated to Solaris 2.6 using
RDBMS/Pro*C 8.1.5. Due to platform and version variances, this article should
be used as a GUIDELINE to understand the Oracle provided makefiles.
Q. I am attempting to statically link my application and receive undefined
symbol errors.
A. You need to map the static library references exactly, including the
repetitions of some static libraries, shown earlier in the section on static
linking.
.
--------------------------