CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Many "undefined reference" errors when linking to shared library

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   April 7, 2016, 20:04
Default Many "undefined reference" errors when linking to shared library
  #1
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
I want to compile pisoFoam as a library instead of as an executable. This is easily achieved by commenting out:

Code:
EXE = $(FOAM_APPBIN)/pisoFoam
in Make/files, adding the line:

Code:
LIB = /path/to/library/libpisoFoam
and running wmake.

This compiles perfectly without any error or warning. However, when I try to link to this shared library I get many "undefined reference" errors. Here is a small sample:

Code:
/path/to/libpisoFoam.so: undefined reference to `Foam::fvMesh::~fvMesh()'
/path/to/libpisoFoam.so: undefined reference to `Foam::dimensionSet::reset(Foam::dimensionSet const&)'
/path/to/libpisoFoam.so: undefined reference to `Foam::pisoControl::pisoControl(Foam::fvMesh&, Foam::word const&)'
/path/to/libpisoFoam.so: undefined reference to `Foam::Vector<double>::typeName'
/path/to/libpisoFoam.so: undefined reference to `Foam::regIOobject::read()'
/path/to/libpisoFoam.so: undefined reference to `Foam::pTraits<double>::typeName'
/path/to/libpisoFoam.so: undefined reference to `Foam::solution::relaxEquation(Foam::word const&) const'
/path/to/libpisoFoam.so: undefined reference to `Foam::regIOobject::rename(Foam::word const&)'
I try to link to the library using the following application (NOTE: I renamed the main function in pisoFoam.C to piso_foam_solver):

Code:
#include <iostream>
#include "pisoFoam.H"

using namespace std;

int main(int argc, char *argv[])
{
    cout << "Hello World!" << endl;

    piso_foam_solver(argc, argv);

    cout << "Bye World!" << endl;

    return 0;
}
which I compile by running:

Code:
g++ test.cpp -I/path/to/header/pisoFoam.H -L/path/to/library -lpisoFoam -o test
I am very new to OpenFOAM and C++ programming. Can someone help me figure out what is going wrong here?
cfbaptista is offline   Reply With Quote

Old   April 8, 2016, 16:59
Default
  #2
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 21
marupio is on a distinguished road
Interesting approach. Try adding all the links that pisoFoam has. Check its Make/options file.
__________________
~~~
Follow me on twitter @DavidGaden
marupio is offline   Reply With Quote

Old   April 8, 2016, 17:25
Default
  #3
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
During one of my (many) attempts I did that and I also included all the #include statements of pisoFoam.C in test.cpp. I then got a different error about a missing header called parRun.H.

Nonetheless, the errors I am facing contradict my understanding of C++ libraries. I would like to argue the following:

Assume some guy creates libFirst.so and another guy creates on top of that libSecond.so. Then I come in and create libThird.so on top of libSecond.so. Is it not the case that I should only care about linking my library to libSecond.so without having any knowledge about how libSecond.so is linked to libFirst.so?

I mean to say that the headers which are included into libSecond.so in order to interface with libFirst.so should not be included again into my library, right?
cfbaptista is offline   Reply With Quote

Old   April 8, 2016, 17:41
Default
  #4
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 21
marupio is on a distinguished road
Including headers differs from linking. You shouldn't need to include any additional headers, just include pisoFoam.H.

I believe dynamically shared objects, (name.so) work this way. libraryC includes B, and if B includes A , then C doesn't have to include A. If they aren't dynamically linked, then this won't work. OF libraries are dynamically linked, but some of the ThirdParty stuff might not be.

I just tried what you're suggesting.

It compiled and linked properly once I included the link paths (options/EXE_INC) from pisoFoam, and only included the pisoLib library (EXE_LIBS = -lpisoLib).
__________________
~~~
Follow me on twitter @DavidGaden
marupio is offline   Reply With Quote

Old   April 8, 2016, 17:55
Default
  #5
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
So if I understand correctly the following is working for you:

Code:
g++ test.cpp -I/opt/openfoam30/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam30/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam30/src/transportModels -I/opt/openfoam30/src/transportModels/incompressible/singlePhaseTransportModel -I/opt/openfoam30/src/finiteVolume/lnInclude -I/opt/openfoam30/src/meshTools/lnInclude -I/opt/openfoam30/src/fvOptions/lnInclude -I/opt/openfoam30/src/sampling/lnInclude -I/path/to/my/header -L/path/to/my/lib -lpisoFoam -o test
cfbaptista is offline   Reply With Quote

Old   April 8, 2016, 18:00
Default
  #6
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 21
marupio is on a distinguished road
You aren't using wmake?

If you are manually assembling the make command, you also have to add include directories for OSspecific/POSIX/lnInclude, OpenFOAM/lnInclude, and you have to link to -lOpenFOAM -ldl. I'm not sure what else, I think it depends on platform and version.
__________________
~~~
Follow me on twitter @DavidGaden
marupio is offline   Reply With Quote

Old   April 8, 2016, 18:12
Default
  #7
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
I use wmake only to compile the pisoFoam library but I do not use wmake to compile the application which uses the library. My final goal is to embed the pisoFoam solver inside a Python application. For the interface between C++ and Python I cannot use wmake. The interfacing requires yet another make tool.
cfbaptista is offline   Reply With Quote

Old   April 12, 2016, 08:10
Default
  #8
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
I managed to link to the library and run the application perfectly without using wmake for compilation. All I needed was to run a bash script with the following content:

Code:
EXE_INC=" \
    -I/path/to/header/pisoFoam.H"

EXE_LIBS=" \
    -L/opt/openfoam30/platforms/linux64GccDPInt32Opt/lib \
    -lturbulenceModels \
    -lincompressibleTurbulenceModels \
    -lincompressibleTransportModels \
    -lfvOptions \
    -L/path/to/lib \
    -lpisoFoam"

g++ $EXE_INC -c test.cpp -o test.o
g++ -Xlinker --no-as-needed test.o $EXE_LIBS -o test
Next to linking to this minimal set of OpenFOAM libraries, the important magic here is -Xlinker --no-as-needed. In old versions of g++ this option was the default. Nowadays you need to specifiy this explicitly as explained here.

Although, I got it to work I still do not understand why I need to link my application to the OpenFOAM libraries. My application is using those libraries only indirectly via libpisoFoam.so. My intuition tells me that directly linking my application to those libraries should be redundant.
cfbaptista is offline   Reply With Quote

Old   April 15, 2016, 06:58
Default
  #9
New Member
 
Carlos Baptista
Join Date: Feb 2016
Location: Rotterdam, The Netherlands
Posts: 14
Rep Power: 10
cfbaptista is on a distinguished road
I managed to discover why I needed to link my application to sub-dependencies. As it turns out when you run wmake, Make/options is read and used fully but when you run wmake libso some things are excluded.

If you compare the output of wmake:

Code:
Making dependency list for source file vorticityFoam.C
g++ -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/opt/openfoam30/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam30/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam30/src/transportModels -I/opt/openfoam30/src/transportModels/incompressible/singlePhaseTransportModel -I/opt/openfoam30/src/finiteVolume/lnInclude -I/opt/openfoam30/src/meshTools/lnInclude -I/opt/openfoam30/src/fvOptions/lnInclude -I/opt/openfoam30/src/sampling/lnInclude -IlnInclude -I. -I/opt/openfoam30/src/OpenFOAM/lnInclude -I/opt/openfoam30/src/OSspecific/POSIX/lnInclude   -fPIC -c vorticityFoam.C -o Make/linux64GccDPInt32Opt/vorticityFoam.o
g++ -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/opt/openfoam30/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam30/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam30/src/transportModels -I/opt/openfoam30/src/transportModels/incompressible/singlePhaseTransportModel -I/opt/openfoam30/src/finiteVolume/lnInclude -I/opt/openfoam30/src/meshTools/lnInclude -I/opt/openfoam30/src/fvOptions/lnInclude -I/opt/openfoam30/src/sampling/lnInclude -IlnInclude -I. -I/opt/openfoam30/src/OpenFOAM/lnInclude -I/opt/openfoam30/src/OSspecific/POSIX/lnInclude   -fPIC -Xlinker --add-needed -Xlinker --no-as-needed Make/linux64GccDPInt32Opt/vorticityFoam.o -L/opt/openfoam30/platforms/linux64GccDPInt32Opt/lib \
            -lturbulenceModels -lincompressibleTurbulenceModels -lincompressibleTransportModels -lfiniteVolume -lmeshTools -lfvOptions -lsampling -lOpenFOAM -ldl  \
             -lm -o /home/cfbaptista/Workspace/OpenFOAM/cfbaptista-3.0.1/bin/vorticityFoam
with the output of wmake libso

Code:
Making dependency list for source file vorticityFoam.C
g++ -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/opt/openfoam30/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam30/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam30/src/transportModels -I/opt/openfoam30/src/transportModels/incompressible/singlePhaseTransportModel -I/opt/openfoam30/src/finiteVolume/lnInclude -I/opt/openfoam30/src/meshTools/lnInclude -I/opt/openfoam30/src/fvOptions/lnInclude -I/opt/openfoam30/src/sampling/lnInclude -IlnInclude -I. -I/opt/openfoam30/src/OpenFOAM/lnInclude -I/opt/openfoam30/src/OSspecific/POSIX/lnInclude   -fPIC -c vorticityFoam.C -o Make/linux64GccDPInt32Opt/vorticityFoam.o
g++ -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/opt/openfoam30/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam30/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam30/src/transportModels -I/opt/openfoam30/src/transportModels/incompressible/singlePhaseTransportModel -I/opt/openfoam30/src/finiteVolume/lnInclude -I/opt/openfoam30/src/meshTools/lnInclude -I/opt/openfoam30/src/fvOptions/lnInclude -I/opt/openfoam30/src/sampling/lnInclude -IlnInclude -I. -I/opt/openfoam30/src/OpenFOAM/lnInclude -I/opt/openfoam30/src/OSspecific/POSIX/lnInclude   -fPIC -shared -Xlinker --add-needed -Xlinker --no-as-needed Make/linux64GccDPInt32Opt/vorticityFoam.o -L/opt/openfoam30/platforms/linux64GccDPInt32Opt/lib \
              -o libNULL.so
'libNULL.so' is up to date.
you will notice that when running wmake libso that, although, the flag for pointing to the directory containing OpenFOAM libraries is present, the flags for actually linking the libraries are missing.

I find this behaviour of wmake libso very strange. Does it always work like this or is my OpenFOAM installation somehow broken?
cfbaptista is offline   Reply With Quote

Reply

Tags
application, compilation error, linking, shared libraries, undefined reference

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Decomposing meshes Tobi OpenFOAM Pre-Processing 22 February 24, 2023 10:23
Foam::error::PrintStack almir OpenFOAM Running, Solving & CFD 91 December 21, 2022 05:50
[snappyHexMesh] Error snappyhexmesh - Multiple outside loops avinashjagdale OpenFOAM Meshing & Mesh Conversion 53 March 8, 2019 10:42
problem loading UDF library in parallel cluster Veera Gutti FLUENT 8 July 26, 2016 08:24
OpenFOAM141dev linking error on IBM AIX 52 matthias OpenFOAM Installation 24 April 28, 2008 16:49


All times are GMT -4. The time now is 03:13.