Building an OCCI project using XCode 3.1

Building an OCCI project using XCode 3.1

With the release of the Instant Client for Mac OS X you can now build OCCI based applications targetting modern Macs using Leopard on Intel. However, there is very little help available for building these apps using XCode, and if you hit the same problem we did (see below) then perhaps this post may be helpful.

Firstly download the Instant Client.  You will need the 'Basic' and 'SDK' packages.  We have unzipped them into '/instantclient_10_2' on the root of the hard disk.  The 'SDK' should unzip into a folder within this one. The OCCI headers (and others) should then be in this path : '/instantclient_10_2/sdk/include'.  You can of course change this to suit your needs but this is what the walkthrough below is based on.

Before getting 'stuck in' though you will need to create a couple if 'links' so that GCC can link to the OCCI libraries.  You can do this using a 'Run Script' in the project but I find it easier just to do this as a 'one off' now.  

  $ ln /instantclient_10_2/libocci.dylib.10.1 /instantclient_10_2/libocci.dylib
  $ ln /instantclient_10_2/libclntsh.dylib.10.1 /instantclient_10_2/libclntsh.dylib

So let's get started!

Firstly, create a new 'C++ Tool' project using XCode :

New C++ Tool

and give it a name, in this case, 'occi' :

Name the project

You will then have your project open in XCode :

Project open in Xcode

Next, double click on the item under 'Targets', in this case 'occi' to bring up the Target Info window.  Switch to the 'Build' tab :

Target Build Settings

Change the following settings (note the 'Search' box in the top right to help you find the settings ):

Other Linker Flags : -locci -lclntsh

Header Search Paths : /instantclient_10_2/sdk/include

Library Search Paths : /instantclient_10_2

Next, open your 'main.cpp' file and try this sample code :

#include <iostream>

/* Oracle */
#include <occi.h>

/* namespaces */
using namespace std;
using namespace oracle::occi;

/* Globals */
Environment * env;
Connection * conn;
int main(int argc, char * argv)
  // Connect
  env = Environment::createEnvironment(Environment::OBJECT);
  conn = env->createConnection("scott", "tiger", "//lcoalhost:1521/xe");
  Statement *stmt = conn->createStatement("SELECT COUNT(*) FROM TAB");
  ResultSet *rs=stmt->executeQuery();
  string ntabs=rs->getString(1);
  cout << "Number of tables " << ntabs << endl;  
  // Close connection etc
  return 0;

Don't forget to change the connection details to the relevant values for your setup.

Next, navigate to the 'Executables' folder of your project and double click on 'occi' to bring up the Executable Info page.  Change to the 'Arguments' tab and add an environment variable for DYLD_LIBRARY_PATH :


Set the value to '/instantclient_10_2'.

You should then be able to 'Build and Go'.   You may want to set a breakpoint or open the Console ('Run -> Console' from the XCode menu) so you can see the results :

Debug console

And that should be it!   However.....

If you do something a little more advanced, which in our case meant using 'ott' (supplied as part of the 'SDK' package for the Instant Client) and building OCCI code based on the Oracle Spatial type (SDO_GEOMETRY) then you will probably get this error at link time :

Undefined symbols:  "oracle::occi::setVector(oracle::occi::AnyData&, 
                    std::allocator<oracle::occi::Number> > const&)", referenced from:
      _main in occi.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

After much digging the problem is with a couple of Preprocessor macros defined by default in XCode, _GLIBCXX_DEBUG=1 and _GLIBCXX_DEBUG_PEDANTIC=1.

Go into the 'Build Settings' for the target as described above, find the Preprocessor Macros entry and remove the two macro definitions.  Note that setting them to 0 does not seem to work.

You should then be good to go!  

Comments (0)

Add a Comment

Please login to comment.