CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Many "undefined reference" errors when linking to shared library (https://www.cfd-online.com/Forums/openfoam-programming-development/169344-many-undefined-reference-errors-when-linking-shared-library.html)

cfbaptista April 7, 2016 19:04

Many "undefined reference" errors when linking to shared library
 
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?

marupio April 8, 2016 15:59

Interesting approach. Try adding all the links that pisoFoam has. Check its Make/options file.

cfbaptista April 8, 2016 16:25

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?

marupio April 8, 2016 16:41

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).

cfbaptista April 8, 2016 16:55

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

marupio April 8, 2016 17:00

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.

cfbaptista April 8, 2016 17:12

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 April 12, 2016 07:10

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 April 15, 2016 05:58

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?


All times are GMT -4. The time now is 01:04.