Bug 13525

Summary: gcc fails load against library with both C++ and C modules
Product: Base System Reporter: bostic <bostic>
Component: gnuAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.2-STABLE   
Hardware: Any   
OS: Any   

Description bostic 1999-09-01 16:20:01 UTC
I'm having trouble with gcc and a dynamic shared library that
includes both C++ and C sources.

I'm using gcc 2.7.2.1 with gld 2.8.1.

I've seen this problem on BSD/OS 4.0 and FreeBSD 3.2-STABLE.

Here are the steps:

1. Build a dynamic shared library that contains both C++ and
   C sources.  (The C++ modules are a thin API on top of the
   C sources -- they call the C modules, but C modules never
   call or reference symbols in the C++ modules.)

2. Build a C-source program and use gcc to link against the
   library.  Errors appear, such as:

abyssinian:build_local {312} cc -g -I. -Wall -W t.c .libs/libdb-3.0.so
t.c: In function `main':
.libs/libdb-3.0.so: undefined reference to `ostream::operator<<(char const *)'
.libs/libdb-3.0.so: undefined reference to `terminate(void)'

3. Confirm that those symbols don't appear in any C modules:

abyssinian:build_local {313} nm -o *.lo | egrep terminate
cxx_app.lo:         U terminate__Fv
cxx_except.lo:         U terminate__Fv
cxx_lock.lo:         U terminate__Fv
cxx_log.lo:         U terminate__Fv
cxx_mpool.lo:         U terminate__Fv
cxx_table.lo:         U terminate__Fv
cxx_txn.lo:         U terminate__Fv

4. Note, you can build the source file correctly if you use C++:

abyssinian:build_local {315} g++ -g -I. -Wall -W t.c .libs/libdb-3.0.so

   works.

Does anybody understand what the problem is, here?

Are there any suggested workarounds?  Is it a bad idea to include
both C++ and C modules in the same library?

How-To-Repeat: Here are the steps:

1. Build a dynamic shared library that contains both C++ and
   C sources.  (The C++ modules are a thin API on top of the
   C sources -- they call the C modules, but C modules never
   call or reference symbols in the C++ modules.)

2. Build a C-source program and use gcc to link against the
   library.  Errors appear, such as:

abyssinian:build_local {312} cc -g -I. -Wall -W t.c .libs/libdb-3.0.so
t.c: In function `main':
.libs/libdb-3.0.so: undefined reference to `ostream::operator<<(char const *)'
.libs/libdb-3.0.so: undefined reference to `terminate(void)'

3. Confirm that those symbols don't appear in any C modules:

abyssinian:build_local {313} nm -o *.lo | egrep terminate
cxx_app.lo:         U terminate__Fv
cxx_except.lo:         U terminate__Fv
cxx_lock.lo:         U terminate__Fv
cxx_log.lo:         U terminate__Fv
cxx_mpool.lo:         U terminate__Fv
cxx_table.lo:         U terminate__Fv
cxx_txn.lo:         U terminate__Fv

4. Note, you can build the source file correctly if you use C++:

abyssinian:build_local {315} g++ -g -I. -Wall -W t.c .libs/libdb-3.0.so

   works.
Comment 1 iedowse freebsd_committer freebsd_triage 2002-01-21 21:17:03 UTC
State Changed
From-To: open->feedback


Does this problem still exist?
Comment 2 iedowse 2002-01-22 01:06:25 UTC
In message <200201212132.g0LLWwH11686@abyssinian.sleepycat.com>, Keith Bostic w
rites:
>Sorry, but I haven't the slightest idea -- it's been 2 1/2 years.
>There's a test case in the PR, so you should be able to find out.

Thanks for the reply - yes, it seems that the issue is still present.
The following script reproduces it directly (cc'd to gnats for
future reference).

Ian

#!/bin/sh

cat > a.c << EOF
void a(void) {}
EOF

cat > b.cc << EOF
#include <iostream.h>
extern "C" { void a(void); } 
class b { public: void A(); };
void b::A() { a(); cout << "a"; }
EOF

cat > c.c << EOF
extern void a(void);
int main() { a(); return 0; }
EOF

gcc -Wall -c -fpic a.c
c++ -Wall -c -fpic b.cc
gcc -shared -o libab.so a.o b.o
gcc -Wall -o c c.c ./libab.so
Comment 3 iedowse freebsd_committer freebsd_triage 2002-01-22 01:11:47 UTC
State Changed
From-To: feedback->open


Still a bug.
Comment 4 Sheldon Hearn 2002-01-31 10:06:21 UTC
On Mon, 21 Jan 2002 17:12:18 PST, iedowse@FreeBSD.org wrote:

> Synopsis: gcc fails load against library with both C++ and C modules
> 
> State-Changed-From-To: feedback->open
> State-Changed-By: iedowse
> State-Changed-When: Mon Jan 21 17:11:47 PST 2002
> State-Changed-Why: 
> 
> Still a bug.

As contributed software, it's very unlikely that this will be fixed
unless it's reported to the GCC distribution maintainers.

Has this been done?

Ciao,
Sheldon.
Comment 5 Gerald Pfeifer freebsd_committer freebsd_triage 2003-04-06 22:22:12 UTC
State Changed
From-To: open->feedback

Have you reported this back to the GCC developers using 
http://gcc.gnu.org/bugs.html ? 
This does not seem to be a FreeBSD-specific issue, so I'll 
probably close this PR (ideally, once you have submitted the 
report to the GCC folks).
Comment 6 Gerald Pfeifer freebsd_committer freebsd_triage 2003-05-21 14:41:18 UTC
State Changed
From-To: feedback->closed

I debugged this in further depth, and it is apparently operator error: As 
soon as you use any C++ library routines (whether directly or indirectly) 
you need to link the final binary using g++, not gcc, and the g++ driver 
then will link any additional libraries required. 

The following would have worked for the example provided: 
gcc -Wall -c -fpic a.c 
c++ -Wall -c -fpic b.cc 
gcc -shared -o libab.so a.o b.o 
gcc -Wall -c c.c 
c++ -o c c.o ./libab.so