gcc .o - 奇怪的鏈接錯誤:命令行中缺少DSO




undefined reference (9)

當我編譯openvswitch-1.5.0時,遇到以下編譯錯誤:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
     -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init  -g -O2 -export-dynamic ***-lpthread***  -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
 /home/jyyoo/src/dpdk/build/lib/librte_eal.a
 /home/jyyoo/src/dpdk/build/lib/libethdev.a
 /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
 /home/jyyoo/src/dpdk/build/lib/librte_hash.a
 /home/jyyoo/src/dpdk/build/lib/librte_lpm.a
 /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
 /home/jyyoo/src/dpdk/build/lib/librte_ring.a
 /home/jyyoo/src/dpdk/build/lib/librte_mempool.a
 /home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm 
     /usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
     to symbol '[email protected]@GLIBC_2.2.5'
     /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from 
     command line

如果我嘗試查看libpthread的符號,它看起來很好。

$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
   199: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 [email protected]@GLIBC_2.2.5
   173: 0000000000008220  2814 FUNC    LOCAL  DEFAULT   13 __pthread_create_2_1
   462: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 [email protected]@GLIBC_2.2

你能提供任何提示或指針嗎?


Answers

我在安裝HPCC基準測試(包括HPL和其他一些基準測試)時發生了同樣的情況。 我在構建腳本中向編譯器標誌添加了-lm ,然後成功編譯。


錯誤消息取決於分發/編譯器版本:

Ubuntu Saucy:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring :(更多信息)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

解決方案:在鏈接階段,您可能在編譯步驟中缺少庫。 在我的情況下,我添加了'-lz'到makefile / GCC標誌。

背景: DSO是一個動態共享對像或共享庫。


我發現我有同樣的錯誤。 我正在編譯一個包含lapack和blas的代碼。 當我改變這兩個圖書館的命令時,錯誤消失了。

“LAPACK_LIB = -llapack -lblas”在其中“LAPACK_LIB = -lblas -llapack”給出了上述錯誤。


我也遇到了同樣的問題。 我不知道為什麼,我只是將-lpthread選項添加到編譯器,一切正常。

舊:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

出現以下錯誤。 如果我將-lpthread選項添加到上面的命令然後確定。

/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol '[email protected]@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

我發現的是,有時連接器抱怨的庫不是導致問題的那個庫。 可能有一個聰明的方法來解決問題的地方,但這是我所做的:

  • 在鏈接命令中註釋掉所有鏈接的庫。
  • 清理掉所有的.o's,.so等等(通常make clean就夠了,但是你可能想要運行一個遞歸的find + rm或類似的東西)。
  • 取消註釋鏈接命令中的庫,並根據需要重新安排訂單。

@peter karasev:我在CentOS7上遇到了與gcc 4.8.2 cmake項目相同的問題。 “target_link_libraries”部分中庫的順序很重要。 我想cmake只是將列表按照原樣傳遞給鏈接器,即它不會嘗試並按照正確的順序進行操作。 這是合理的 - 當您考慮它時,cmake無法知道正確的順序是什麼,直到鏈接成功完成。


請添加: CFLAGS="-lrt"LDFLAGS="-lrt"


在編譯目標文件之後 ,應該在命令行中提到庫:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
     -g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
     lib/libopenvswitch.a \
     /home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
     -lrt -lm -lpthread 

說明:鏈接取決於模塊的順序。 首先請求符號,然後從具有它們的庫中鏈接。 所以你必須指定首先使用庫的模塊,以及後面的庫。 喜歡這個:

gcc x.o y.o z.o -la -lb -lc

此外,如果存在循環依賴性,則應多次在命令行上指定相同的庫。 因此,如果libb需要來自libc符號,並且libc需要來自libb符號,那麼命令行應該是:

gcc x.o y.o z.o -la -lb -lc -lb

當我使用distcc創建我的c ++項目時,同樣的問題發生在我身上; 最後我用export CXX="distcc g++"解決了它。


這與你所要求的類似,是(我希望)標準C ++ ......

#include <iostream>

template<typename C, typename T, T (C::*getter)(), void (C::*setter)(const T&)>
struct Property
{
    C *instance;

    Property(C *instance)
        : instance(instance)
    {
    }

    operator T () const
    {
        return (instance->*getter)();
    }

    Property& operator=(const T& value)
    {
        (instance->*setter)(value);
        return *this;
    }

    template<typename C2, typename T2,
             T2 (C2::*getter2)(), void (C2::*setter2)(const T2&)>
    Property& operator=(const Property<C2, T2, getter2, setter2>& other)
    {
        return *this = (other.instance->*getter2)();
    }

    Property& operator=(const Property& other)
    {
        return *this = (other.instance->*getter)();
    }
};

//////////////////////////////////////////////////////////////////////////

struct Foo
{
    int x_, y_;

    void setX(const int& x) { x_ = x; std::cout << "x new value is " << x << "\n"; }
    int getX() { std::cout << "reading x_\n"; return x_; }

    void setY(const int& y) { y_ = y; std::cout << "y new value is " << y << "\n"; }
    int getY() { std::cout << "reading y_\n"; return y_; }

    Property<Foo, int, &Foo::getX, &Foo::setX> x;
    Property<Foo, int, &Foo::getY, &Foo::setY> y;

    Foo(int x0, int y0)
        : x_(x0), y_(y0), x(this), y(this)
    {
    }
};

int square(int x)
{
    return x*x;
}

int main(int argc, const char *argv[])
{
    Foo foo(10, 20);
    Foo foo2(100, 200);
    int x = foo.x; std::cout << x << "\n";
    int y = foo.y; std::cout << y << "\n";
    foo.x = 42; std::cout << "assigned!\n";
    x = foo.x; std::cout << x << "\n";
    std::cout << "same instance prop/prop assign!\n";
    foo.x = foo.y;
    std::cout << "different instances prop/prop assign\n";
    foo.x = foo2.x;
    std::cout << "calling a function accepting an int parameter\n";
    std::cout << "square(" << foo.x << ") = " <<  square(foo.x) << "\n";
    return 0;
}

正如您在main中看到的那樣,只要您指定類型為T值(此處為int )或可隱式地將T轉換為T屬性,並且只要您在讀取時將它們轉換回T值,就可以使用透明用法。

行為將是不同的但是,例如,如果您將foo.x傳遞給模板函數,因為foo.x的類型不是int而是Property<Foo, int, ...>

您也可能遇到非模板函數的問題...調用接受T值的函數將正常工作,但是T&參數例如會成為一個問題,因為基本上該函數要求變量直接使用該地址訪問。 出於同樣的原因,您當然不能將屬性的地址傳遞給接受T*參數的函數。





gcc compiler-errors linker undefined-reference