编译自己的求解器遇到问题“undefined reference”



  • Hello,各位大神,

    我在编译自己一个求解器的过程中出现了如下的问题:提示说有用undefined reference.

    -lincompressibleTransportModels -lOpenFOAM -ldl  \
         -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
    Make/linux64GccDPInt32Opt/dynaPorousNetFoam.o: In function `main':
    dynaPorousNetFoam.C:(.text.startup+0x1408): undefined reference to `Foam::netPanel::~netPanel()'
    dynaPorousNetFoam.C:(.text.startup+0x1f01): undefined reference to `Foam::netPanel::netPanel(Foam::dictionary const&)'
    ......
    ......
    dynaPorousNetFoam.C:(.text.startup+0x68c5): undefined reference to `Foam::netPanel::~netPanel()'
    collect2: error: ld returned 1 exit status
    /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
    make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
    
    

    下面说一下我编译的程序结构,我的dynaForousNetFoam 求解器是基于PisoFOAM 进行简单修改后编译的。这个新的求解器调用了我自己写的一个class创建了porousZones 对象,并利用相关的成员函数对U 方程进行修改。
    这个class 名是netpanel,并且这个类可以单独用wmake编译成功,结果如下:

    .
    ├── platforms
    │   └── linux64GccDPInt32Opt
    │       ├── bin
    │       └── lib
    │           └── netPanel.so
    └── run
    
    

    我求解器中部分相关的代码:

    ...
    netPanel porousZones(netDict);  // constrcut net panel
    porousZones.updatePoroField(porosityField, mesh, structuralPositions,structuralElements);
    //- write the porosity field
    porosityField.write();
    ...
    // add source term to  U equation
    porousZones.addResistance(UEqn,nu,mesh,structuralPositions,structuralElements);
    ...
    

    下面是我在编译dynaForousNetFoam 时用的file 和options 文件。从option中可以看出我在编译dynaForousNetFoam的时候已经链接到我之前写的那个class了,但是编译还是不通过。
    File:

    dynaPorousNetFoam.C
    EXE = $(FOAM_USER_APPBIN)/dynaPorousNetFoam
    

    Option:

    EXE_INC = \
        -I./Netpanels/lnInclude \
        -I$ (LIB_SRC)/finiteVolume/lnInclude \
        -I$(LIB_SRC)/meshTools/lnInclude \
        -I$(LIB_SRC)/sampling/lnInclude \
        -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
        -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
        -I$(LIB_SRC)/transportModels \
        -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel
    
    EXE_LIBS = \
        -L$(FOAM_USER_LIBBIN)\ -lnetPanel \
        -lfiniteVolume \
        -lfvOptions \
        -lmeshTools \
        -lsampling \
        -lturbulenceModels \
        -lincompressibleTurbulenceModels \
        -lincompressibleTransportModels
    

    所以有没有大神能够帮忙指点一下?


  • OpenFOAM讲师

    (1)wclean清空所有的文件,再编译看看(2)你自己的Class编写有问题,自己查找(3)看样子是想添加源项,直接在方程中添加可否



  • @yfclark

    1. wclean/ wmake 已经很多次了,每次都是自己写的class可以先编译成功,并生成netPanel.so 这个lib。但是dynaPorousNetFoam.C 就编译出现问题。
    2. 如果自己写的class有问题的话,是不应该在第一步编译的时候就会出现问题?
    3. 因为研究的对象不是充满整个计算域,只有特定的范围内的网格才有源项。 又因为研究对象有大变形,不同时间对应不同的网格,所以不能直接在方程中添加源项。
    4. 所以我自己写的class就是根据结构的空间位置,找出对应的网格,并在这些网格中添加源项。

  • OpenFOAM讲师

    编译过了只是说明你骗过了编译器不代表程序没有问题,你说的可以直接添加源项解决,通过访问mesh的cells或者face解决



  • @yfclark编译自己的求解器遇到问题“undefined reference” 中说:

    编译过了只是说明你骗过了编译器不代表程序没有问题,你说的可以直接添加源项解决,通过访问mesh的cells或者face解决

    那个netpanel的class的作用就是找到特定的mesh,并在cells决添加源项。


  • OpenFOAM讲师

    试一下

    //create volfield as source term
    //initial it as zero
    //forAll(mesh,celli)
    {
            if condition  
       S[celli]=your value
    }
    

    自己琢磨一下



  • @yfclark
    这个function, 我已经写到我的class中了,但是问题是在编译求解器时遇到问题“undefined reference”

    void Foam::netPanel::addResistance
            (
                fvVectorMatrix&         UEqn,
                const volScalarField&   nu,
                const fvMesh&           mesh_,
                const volVectorField&   structuralPositions,
                const volVectorField&   structuralElements
            )
            {
                const vectorField& centres(mesh_.C());
                forAll(structuralElements,Elementi)
                {
                    dimensionedTensor d_(tensor::zero);
                    dimensionedTensor f_(tensor::zero);
                    transformCoeffs(D_,d_,structuralPositions,structuralElements[Elementi]);
                    transformCoeffs(F_,f_,structuralPositions,structuralElements[Elementi]);
                    tensor& dvalue = d_.value();
                    tensor& fvalue = f_.value();
                    const scalarField V = mesh_.V();
                    vectorField& Usource = UEqn.source();
                    const vectorField& U = UEqn.psi();
            
                    forAll(centres, cellI)
                    {
                        if(isInPorousZone(centres[cellI],structuralPositions,structuralElements[Elementi]))
                         {
                        tensor dragCoeff = nu[cellI]*dvalue + 0.5*mag(U[cellI])*fvalue;
                        Usource[cellI] -=V[cellI]*dragCoeff & (U[cellI] );
                         }
                    }
                }
            
            }
    

  • OpenFOAM讲师

    老哥,你这么老实,你直接函数式编程不就行了嘛,非要写class



  • 我在想是不是 我的这个option里买有格式错误。
    我试过将

    EXE_LIBS = \
        -L$(FOAM_USER_LIBBIN)\ -lnetPanel \
    

    改为

    EXE_LIBS = \
        -L$(FOAM_USER_LIBBIN) -lnetPanel \
    

    结果感觉更错啦

         -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
    /usr/bin/ld: cannot find -lnetPanel
    collect2: error: ld returned 1 exit status
    /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
    make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
    
    


  • undefined reference可能出现在你的虚函数,具体什么问题不太清楚,检查下你的成员函数



  • @东岳 感谢东岳老师回复,我又看了一下错误提示,出现问题的都是我写的虚函数。


  • OpenFOAM教授

    @huiCfd 构造函数和析构函数是不是忘记定义了?



  • @wwzhao 赵教授,这两个函数我记得定义了,

        // Constructors
           netPanel
           (
               const dictionary&        netDict
           );
    
        //- Destructor
        ~netPanel();
    

    但是我有一点不太明白,为什么有的函数后面有一个const,有的没有。例如:
    这个虚函数是void funname() const;

    void addResistance
            (
                fvVectorMatrix&         UEqn,
                const volScalarField&   nu,
                const fvMesh&           mesh,
                const matrix&   structuralPositions,
                const matrix&   structuralElements
            )const;
    

    而这个函数是 bool funname(); 就没有const了。

            bool isInPorousZone
            (
                const point             x,
                const volVectorField&   structuralPositions,
                const vector&           structuralElementi
            );        
    

    const 在括号里面我知道是可以保证传入的参数不变,但是在外边是啥意思啊?



  • @huiCfd
    这个函数后面的const 是用来保护类的成员数据不发生改变。


  • OpenFOAM教授

    @huiCfd 你这个只是声明(declaration),有没有具体的定义(definition)?



  • @wwzhao
    定义也是有的。如下

    Foam::netPanel::netPanel
    (
        const dictionary&        netDict
    )
    :   // initial components
        netDict_(netDict),
        porousPropertiesDict_(netDict_.subDict("porousProperties")),
        porosity_(readScalar(porousPropertiesDict_.lookup("porosity"))),
        thickness_(readScalar(porousPropertiesDict_.lookup("halfthickness")))
        // D_(readVector(porousPropertiesDict_.lookup("D"))),  // initial as zeros
        // F_(readVector(porousPropertiesDict_.lookup("D")))  // initial as zeros
    {
        dimensionedVector D_(porousPropertiesDict_.lookup("D"));
        dimensionedVector F_(porousPropertiesDict_.lookup("F"));
    
    }
    

  • OpenFOAM教授

    @huiCfdnetPanel.so 重命名成 libnetPanel.so 试试呢?



  • @wwzhao 不行。。


  • OpenFOAM教授

    @huiCfd $(FOAM_USER_LIBBIN) 后面的换行符去掉了吗?



  • @wwzhao 是的,去掉何不去掉都试过了,
    去掉后显示的错误是

     -lm -o /home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam
    /usr/bin/ld: cannot find -llibnetPanel
    collect2: error: ld returned 1 exit status
    /opt/OpenFOAM/OpenFOAM-v1906/wmake/makefiles/general:140: recipe for target '/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam' failed
    make: *** [/home/hui/OpenFOAM/hui-v1906/platforms/linux64GccDPInt32Opt/bin/dynaPorousNetFoam] Error 1
    

    没去掉的话跟原来的错误一样,都是undefined reference


  • OpenFOAM教授

    @huiCfd
    1、去掉$(FOAM_USER_LIBBIN)后的换行符,注意后面的 netPanel 前不要加lib

    EXE_LIBS = \
        -L$(FOAM_USER_LIBBIN) -lnetPanel \
    

    2、编译出来的 netPanel.so 文件重命名为 libnetPanel.so



  • @wwzhao
    成功了啊! 非常感谢。。
    是不可以总结如下经验:

    1. 自己编写的类在编译时一定要以lib开头,
    2. 然后在编译主程序时,$(FOAM_USER_LIBBIN)后面不能有换行符,
    3. -l之后直接跟自己编译的东西但是要去掉lib


  • @huiCfd 可能这个适用于of1906


  • OpenFOAM教授

    说明一下:

    1、换行符(\)不能随便用,必须用在行尾。如果用在行中间,那么换行符后面的内容都会被忽略,所以你加的 -lnetPanel 没用。

    2、-lfoo 会找名为 libfoo.so 的库文件,-l:bar.so 则会找 bar.so 文件,这是 gcc 的链接规则。



  • @wwzhao 非常感谢指点迷津!


Log in to reply
 

CFD中文网 2016 - 2020 | 京ICP备15017992号-2