My huge reply to this thread (which is a problem/solution report) appears below 
the ==== separator line.  If you found this email posting to be
Helpful, please drop me an email.

- Brian

________________________________________
From: Jonathan Leffler [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, August 10, 2005 4:53 PM
To: CAMPBELL, BRIAN D (BRIAN)
Cc: DBI Users Mailing List
Subject: Re: Informix DBD build on Windows - Better


    -----Original Message-----
    On 8/8/05, CAMPBELL, BRIAN D (BRIAN) <[EMAIL PROTECTED]> wrote:

    All in all I uncovered 9 bugs in the build process for DBD.
    Should I go ahead and publish my findings to this mailing list (DBI
    users)?

As Ron said ("Publish and Be Damned")

Yes - please post bug reports - preferably with the patches to fix them - to 
the list.  They may help other people; eventually, they'll help me help you.

As discussed wholly separately, t08fork.t  failures indicate problems in the 
test, and t91udts.t failures indicate that the database wasn't as clean as it 
should be (arguably a  test problem in itself).  Not dreadfully significant, 
though both should ideally be fixed. 

-----Original Message-----
From: CAMPBELL, BRIAN D (BRIAN) [mailto:[EMAIL PROTECTED]
Sent: Wednesday, August 03, 2005 4:42 PM
To: 'dbi-users@perl.org'

I tried building the recently released Informix DBD 2005.02 today.  I 
apparently have a successful compile and link. But I'm having a major problem 
on the test.  Below is the link input and output, and the first test.  All 
remaining tests look like the first test.  Help and suggestions needed.  Here's 
the message I'm getting upon running the first test (and all the rest).
 
Can't find 'boot_DBD__Informix' symbol in ./Informix.dll

[stuff snipped]

My Environment:
*  Windows 2000 [Version 5.00.2195] SP4 
*  ActiveState Perl v5.8.7 built for MSWin32-x86-multi-thread, Binary build 813 
[148120] 
*  DBI: 1.48 
*  ESQL: IBM Informix CSDK Version 2.90, IBM Informix-ESQL Version 2.90.TC1 
*  Microsoft Visual C++ 6.0 
*  Connection to Informix DB server 9.21.FC4 on an Alpha box running Compaq 
Tru64 Unix. 
 
========================================================================


This posting documents the problems I had while trying to build the recently
released Informix DBD 2005.02 on Windows.

First of all, the makefile generator produces this notice for Windows systems:

        This is a semi-experimental version of Makefile.PL with Win32 (NT)
        support.  Previous versions have been tested on NT, but there could
        still be bugs in this code.  Please help save the world by trying
        to debug the NT code and reporting the results back to the DBI
        Users mailing list.

So once again, here I go, saving the world...

In the documetation below, I use the following "pattern language" for
each problem:
The symptom - the message from the console.
The reason - my best guess on what is causing the symptom.
A workaround (sometimes) - I provided an expediant "Workaround", which
    I used to keep going.
A recommended solution - Usually just a description and nothing as fancy
as a real patch.

A preliminary remark: I recently upgraded my Perl to 5.8.7.  In doing so,
I took my own previous advice and installed it in "C:\Perl" which I believe
is the default path provided by the ActiveState installer.  Previously,
it was installed in "C:\Program Files\Perl", per a local site installation
process.  Having that blank char in the Perl path caused all kinds of grief
in previous build attempts, as well documented in my previous post on the
subject:
   http://www.mail-archive.com/dbi-users@perl.org/msg19771.html
The majority of problems I encountered then had that one root cause.
The build process uses several Perl modules to due some preliminary set
up; these modules were not good at handling spaces in file paths.
Thus, I was able to avoid a class of problems I had encountered previously.
It was also helpful to use my Batch file tip and CPAN/Config.pm tip as
described near the bottom of that posting.


OK, now on to the problem set...


Problem 1
=========

Symptom:

When running the makefile generator (Makefile.pl):

This warning occurs:

Note: Some of the code here or in ESQL/C may work properly if
%INFORMIXDIR% contains spaces.

Then I got this:

'C:\Program' is not recognized as an internal or external command, operable 
program or batch file.

Reason:

The cautionary note is true about the "spaces" concern, but is mistaken
about the env var when running under Windows.  It didn't help when I changed
my INFORMIXDIR var from:
   C:\Program Files\Informix\Client-SDK
to:
   C:\Progra~1\Informix\Client-SDK

The script's path of execution for Windows does not look at the %INFORMIXDIR%
env var. Instead, the script locates the Informix folder value by searching
all folders in the PATH list, testing if ESQL.EXE is located in any of them,
and then trims \BIN from the discovery.

The problem with this "PATH search" approach is that the PATH is typically
set by the Informix SDK installation using the file name with blanks.

Workaround:

One can update their PATH setting to remove the blanks or do what I did.
I put the perl Makefile.pl in a batch script, and temporarily altered the
PATH list to include my preferred path as follows.  It used my path instead
of the installation path, because mine comes first.

SET INFORMIXDIR=C:\Progra~1\Informix\Client-SDK
PATH %INFORMIXDIR%\bin;%PATH%
perl Makefile.pl

Recommended solution:

When running under Windows:
The Makefile.pl script should consider using INFORMIXDIR, if present.
The script should at least test for blanks and complain when blanks are found.
Or better yet, translate the path to the alternate 8.3 "blankless" name
(Win32::GetShortPathName may be of help here).


Problem 2
=========

Sympton:

When running the makefile:

dbdimp.ec(32) : fatal error C1083: Cannot open include file: 'unistd.h': No 
such file or directory
 
Reason:

File dbdimp.ec has this, which doesn't compile in MSVC.

#include <unistd.h>

Recommended solution:

Replace the line with the following solution found in ixblob.ec.

#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif /* _WIN32 */


Problem 3
=========

Symptom:

When running the makefile:

ixblob.ec(126) : error C2065: 'F_OK' : undeclared identifier

Reason:

File ixblob.ec refers to the undefined symbol F_OK, whis is passed to the
function access (declared in io.h).  My verions of MSVC doesn't define the
symbol.

Recommended solution:

Add this to the file.  The definition comes from my Unix platform in
<sys/access.h>.  It would seem that the same defined value works on Windows
too.

#ifdef _WIN32
#define F_OK    00              /* E_ACC does file exist */
#endif /* _WIN32 */


Problem 4
=========

Symptom:

When running the makefile:

'INFORMIXC' is not recognized as an internal or external command, operable 
program or batch file.

Reason:

This line is in the makefile.

LD = INFORMIXC='$(FULLPERL) esqlld' ESQLLD='link $(LDDLFLAGS)' $(LDCMD)

This defines a system command which includes the INFORMIXC and ESQLLD as
Unix-style shell parameters preceding the command $(LDCMD). A reference to
LD is here in the Informix.dll target $(INST_DYNAMIC).  Shell parameters
don't work on Windows.
  
 $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) 
$(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) 
$(INST_DYNAMIC_DEP)
        $(LD) -out:$@ $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) $(MYEXTLIB) 
$(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)
        $(CHMOD) $(PERM_RWX) $@

Workaround:

Remove the paramaters from the LD definition:

LD = $(LDCMD)

Modify the Informix DLL target (where LD is referenced) to have ESQLLD and 
ESQLLD
on separate lines (in DOS style without quotes).

 $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) 
$(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) 
$(INST_DYNAMIC_DEP)
  SET INFORMIXC=$(FULLPERL) esqlld
  SET ESQLLD=link $(LDDLFLAGS)
        $(LD) -out:$@ $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) $(MYEXTLIB) 
$(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)
        $(CHMOD) $(PERM_RWX) $@

Recommended solution:

For Windows systems, have the make file generator Makefile.pl create the
makefile lines as described above.


Problem 5
=========

Symptom:

When running the makefile:

'-out' is not recognized as an internal or external command, operable program 
or batch file.

Or at least I think that's what I got (I don't have a saved record of this
this portion of my build).

Reason:

Makefile sets the LD command using this:

LD = INFORMIXC='$(FULLPERL) esqlld' ESQLLD='link $(LDDLFLAGS)' $(LDCMD)

Or modified as this, using the solution from Problem 4:

LD = $(LDCMD)

And later in the file, this sets LDCMD to the ESQLC "wrapper" around the linker.

LDCMD = $(ESQL)

The linker command LDCMD is defined late in the file, so variable LD sees
the ESQLC command value as an undefined empty string.  

Workaround:

Move the LDCMD= definition before the LD= definition.
Or just set LD to $(ESQL).
Or just replace $(LD) with $(ESQL) in the Informix.dll target.

Recommended solution:

Have the make file generator Makefile.pl generate a makefile
using one of the above alternatives.


Problem 6
=========

Symptom:

When running the makefile:

msvcrt.lib(crtexe.obj) : error LNK2001: unresolved external symbol _main
Informix.exe : fatal error LNK1120: 1 unresolved externals

In the makefile target, described above, LDDLFLAGS includes the option:
   -dll
Which is the incorrect ESQLC option for creating .DLL.  Thus, it tries to create
a complete program and complains because an implementation for "main()" can't
be found.

Workaround:

Change the option in LDDLFLAGS to be:
   -target:dll
As documented in IBM publication: 
  Informix-ESQL/C, Programmer's Supplement for Microsoft Windows Environments
  
Recommended solution:

Have the make file generator Makefile.pl define LDDLFLAGS as described above.


Problem 7
=========

Symptom:

When running the supplied tests, virtually every test file returned something
like this:

t/t00basic..........install_driver(Informix) failed: Can't find 
'boot_DBD__Informix' symbol in ./Informix.dll
 at (eval 1) line 3
Compilation failed in require at (eval 1) line 3.

 at D:\build\DBD\DBD-Informix-2005.02\blib\lib/DBD/Informix/TestHarness.pm line 
185
t/t00basic..........dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-41
        Failed 41/41 tests, 0.00% okay
        
Reason:

It took me a while to dig into this one.  I had to understand, to some extent,
what was going in on the code, in the file Informix.c.  This is file is
automatically generated from a "XS" language in Informix.xs and uses macros
extensively. At the suggestion of a colleague, I ran the c-preprocessor to see
what was really being compiled in the Informix.c file.  And what symbols were
put in the .DLL by looking at the link map.  Long story short, all the symbols
in Informix.c were omitted from the DLL because a required "Informix.def" file
was NOT properly passed to the MSVC linker.  That was because it was not
properly specifed on the ESQL command.

These lines occur in the makefile:

BASEEXT = Informix
EXPORT_LIST        = $(BASEEXT).def
        $(LD) -out:$@ $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) $(MYEXTLIB) 
$(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)

The token -def: should not appear.  The argument is just supposed to be a bare
file according to the IBM publication: 
  Informix-ESQL/C, Programmer's Supplement for Microsoft Windows Environments
  
Workaround:

I expect that just removing the -def: prefix from the EXPORT_LIST reference,
above, should work.  But before I spotted that in the file, my solution was
to add the file to the LDDLFLAGS variable:

LDDLFLAGS = ...stuff here... Informix.def

Recommended solution:

Have the make file generator Makefile.pl define the def option as described
above (remove the prefix -def:).


Problem 8
=========

Symptom:

When running the supplied tests, virtually every test file failed.  The Informix
DLL was crashing.  I don't have an exact record of this portion of the build,
but the symptom look similar to that of Problem 7.


Background and Reason:

I recognized this problem, having patched it in previous builds of the
Informix DBD I have built in 2003 and 2004.  I think it's crashing because
it's freeing memory from a different pool (using free) that it was allocated
(needs to use SqlFreeMem instead per PTS Bug B83831).

Workaround:

In dbdimp.ec add this above the function: count_descriptors 
#define PERL_OBJECT 
This must be place "low" in the file; placing this "high" in the file cause
compile errors on includes. 

Recommended Solution:

Not sure.  Add this to the dbdimp.ec file?  (But not too high in the file.)

#ifdef _WIN32
#define PERL_OBJECT 
#endif /* _WIN32 */


Problem 9
=========

Symptom:

DBI Can't load Informix DBD in my own scripts.

Reason:
When running the installation process, 3 files did not get copied to:
   C:\Perl\site\libs\auto\DBD
I think they needed to be in a similar path in the build folder I was using.
I don't think the makefile put them there; it left them in the top level of
the build folder.

Workaround:

I copied them manually.  They were.
Informix.dll
Informix.exp
Informix.lib

Recommended Solution:

The makefile needs to ensure the link output gets into the proper place in the
build folder before the installation step.


Other Issues
============

All tests passed, except 4 were skipped and two tests had failures:
  t\t08fork.t
  t\t91udts.t

The first test produced this message:

Informix has no driver CLONE() function so is unsafe threaded DBD::Informix::db 
prepare failed: handle 2 is owned by thread 15e6014 not current thread 214b68c 
(handles can't be shared between threads and your driver may need a CLONE 
method added) at t\t08fork.t line 32.

This message is cryptic to me, but suggests to me that an Informix connection
can't span multiple threads.

Several messages from the 2nd test appeared similar to:

DBD::Informix::db do failed: SQL: -9991: Named row type (dbd_ix_udts_named) 
already exists in database. at 
D:\build\DBD\DBD-Informix-2005.02\blib\lib/DBD/Informix/TestHarness.pm line 347.

This and other output suggests to me that the testplan can't clean up User
defined data types in the database that were created in an earlier test.
It wants to clean them up, in order to recreate them in a new test.

That's it.

Reply via email to