質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1740閲覧

[C++] ライブラリの静的リンクとその利用

tnkkk

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/29 08:06

編集2020/03/29 13:10

サードパーティのライブラリを静的リンクした自作のライブラリを 静的 or 動的 リンクして利用したい

サードパーティを静的リンクした(はずの)自作のライブラリがあります。
これをまた別のプログラムにリンクしようとしたときに、
リンクエラーが発生します。

コンパイルとライブラリの生成コマンド

※オプジェクトがたくさんあるので抜粋

$ g++ -w -O3 -std=c++1z -m64 -static -static-libstdc++ -I/usr/local/include -c calc.cpp -o calc.o -L/usr/local/lib -lopenblas -lm -lpthread $ ar r libmylib.a calc.o

生成されたオブジェクトの中身

上記で静的リンクされたライブラリが生成される認識なのですが、
オブジェクトの中身の確認するとサードパーティのライブラリの関数が、
Undefine(U cblas_dgemm)になっているように見えます。

$ nm libmylib.a calc.o: 0000000000000000 r .LC0 0000000000000000 V DW.ref.__gxx_personality_v0 U _GLOBAL_OFFSET_TABLE_ 0000000000000000 t _GLOBAL__sub_I__ZN2la4blas4calc3dotERKNS_3MtxES4_ U _Unwind_Resume U _ZN2la3Mtx3mtxERKmS2_ U _ZN2la3MtxD1Ev 0000000000000000 T _ZN2la4blas4calc3dotERKNS_3MtxES4_ U _ZNSt8ios_base4InitC1Ev U _ZNSt8ios_base4InitD1Ev 0000000000000000 b _ZStL8__ioinit U __cxa_atexit U __dso_handle U __gxx_personality_v0 U __stack_chk_fail U cblas_dgemm

実際のソースコードは下記

#include "lapt/3rdparty/blas/calc.hpp" #include <cblas.h> using namespace std; using namespace la; using namespace la::blas; Mtx calc::dot(const Mtx &a, const Mtx &b) { Mtx m = Mtx::mtx(a.rows, b.cols); #ifdef LVAL_DBL cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m.rows, m.cols, a.cols, 1.0, a.p, a.cols, b.p, b.cols, 0.0, m.p, m.cols); #else cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m.rows, m.cols, a.cols, 1.0, a.p, a.cols, b.p, b.cols, 0.0, m.p, m.cols); #endif return m; }

発生している問題・エラーメッセージ

そのライブラリを別のプログラムにリンクしようとすると、
案の定リンクエラーが発生します。

$ g++ -o main main.o -lmylib ~~~ libmylib.a(calc.o): In function `la::blas::calc::dot(la::Mtx const&, la::Mtx const&)': calc.cpp:(.text+0x6c): undefined reference to `cblas_dgemm' ~~~

おそらくサードパーティを自作のライブラリにリンクする時点で、
静的リンクができていないのではないかと思っておりますが、
何か不足している処理やコマンドのミスがあるのでしょうか?

静的リンクをすると、そのリンク元のオブジェクトが無くとも、
別のプログラムで利用できるという認識でいるのですが、
そもそもその認識が間違いでしょうか?

なにか良いデバッグ方法などありましたら、
ご教授いただけますと幸いです。

補足情報

$ g++ --version g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ ar --version GNU ar (GNU Binutils for Ubuntu) 2.30 Copyright (C) 2018 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) any later version. This program has absolutely no warranty.

解決方法

自己解決ではない場合の解決方法をどこに書いたらいいかわからないのでここに書きますが、@Chironianさんの「①サード・パーティのライブラリと自作ライブラリをあらためてアーカイブする」で解決しました。

$ ar -M AR >create libmylib.a # 出力するアーカイブ名 AR >addlib libmylib.a # 自作ライブラリのアーカイブを追加 AR >addlib /usr/local/lib/libopenblas.a # サードパーティのアーカイブを追加 AR >save AR >end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

意外にlinuxのリンクは「直感的」ではないので難しいです。

静的リンク・ライブラリは単なるobjファイル群のアーカイブに過ぎません。
ですので、自作のライブラリを静的リンクにする場合は、①サード・パーティのライブラリと自作ライブラリをあらためてアーカイブするか、②ターゲットのアプリに両方のライブラリをリンクする必要があります。

自作ライブラリを動的リンクにする場合は、サード・パーティのライブラリを-fPICオプション付きでコンパイルする必要があるようです。
-fPICオプションについて調査

投稿2020/03/29 08:16

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tnkkk

2020/03/29 13:02

こんにちは。ご回答ありがとうございます。 「①サード・パーティのライブラリと自作ライブラリをあらためてアーカイブする」で解決いたしました! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問