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

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

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

make は、ビルド作業を自動化するツールです。さまざまなファイルの最終変更時刻を比較し、従属するファイルよりも「ターゲット」のファイルが古いことがわかったときユーザーが設定していた命令を実行する事が可能です。

makefile

make は、プログラムのビルド作業を自動化するツールです。コンパイル、リンク、インストール等のルールを記述したテキストファイルをmakefileと呼び、このルールに従ってmakeが自動的にビルドを実行する。

Ubuntu

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

C++

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

Q&A

解決済

3回答

3475閲覧

C++ コンパイル undefined reference to

MF_19

総合スコア27

make

make は、ビルド作業を自動化するツールです。さまざまなファイルの最終変更時刻を比較し、従属するファイルよりも「ターゲット」のファイルが古いことがわかったときユーザーが設定していた命令を実行する事が可能です。

makefile

make は、プログラムのビルド作業を自動化するツールです。コンパイル、リンク、インストール等のルールを記述したテキストファイルをmakefileと呼び、このルールに従ってmakeが自動的にビルドを実行する。

Ubuntu

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

C++

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

0グッド

0クリップ

投稿2018/07/10 04:01

編集2018/07/10 08:01

前提・実現したいこと

C++でmakeファイルを用いてコンパイルをしようとしていますが、
エラーとなります。

libtest.soファイルをmake(1度目)でコンパイルしたのち、
main.cppを用いて2度目のmakeでコンパイルをしようとしています。
*当然ですが1度目と2度めのmakeファイルは別物です

ここで1度目のmakeはコンパイルが成功して
libtest.soを作成していますが、
2度目のmakeで下記の通りibtest.soにundefinedのものがあると
なっています。

3つがundefinedとなっておりますが、
sourceディレクトリ内(.cpp)のファイルには定義があり、
includeディレクトリ内(.h)にもpthreadpool_compute_1d'を含む関数の定義はありますが、pthreadpool_compute_1d'自体の定義はありませんでした。

ここが問題でしょうか?それとも別の部分のパス指定などが怪しいでしょうか。
ここが問題の場合、具体的にどのように記載すべきか教えて頂ければと思います。

定義を試してみましたが、上手くいっていません。

ちなみに一度目のmakeファイルを修正して解決したいです。

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

2度目のmakeファイル実行時

g++ -std=gnu++14 -Ofast -fPIC -fopenmp -o main obj/main.o ./libtest.so ./libtest.so: undefined reference to `pthreadpool_compute_1d' ./libtest.so: undefined reference to `nnp_convolution_inference' ./libtest.so: undefined reference to `pthreadpool_compute_2d' collect2: error: ld returned 1 exit status Makefile:27: recipe for target 'main' failed make: *** [main] Error 1

該当のソースコード

1度目のmakeファイル

c++

1NNPACK=1 2 3COMPILER = g++ 4CFLAGS :=-std=gnu++14 -Ofast -fPIC -fopenmp -g 5CUFLAGS:=-Wall -Wno-unknown-pragmas -Wfatal-errors -Ofast -fPIC -fopenmp 6LDFLAGS := -lm -lpthread -lgomp -static-libstdc++ -static-libgcc 7 8INCLUDE = -I./include -I/usr/include 9 10ifeq ($(NNPACK), 1) 11CFLAGS+= -DNNPACK 12LDFLAGS+= /home/NNPACK/lib/libnnpack.a /home/NNPACK/lib/libpthreadpool.a /home/NNPACK/lib/libcpuinfo.a 13endif 14 15TARGET = ./test 16DLIB = ./libtest.so 17SRCDIR = ./source 18ifeq "$(strip $(SRCDIR))" "" 19 SRCDIR = . 20endif 21SOURCES = $(wildcard $(SRCDIR)/*.cpp) 22OBJDIR = ./obj 23ifeq "$(strip $(OBJDIR))" "" 24 OBJDIR = . 25endif 26OBJECTS = $(addprefix $(OBJDIR)/, $(notdir $(SOURCES:.cpp=.o))) 27DEPENDS = $(OBJECTS:.o=.d) 28 29all: $(TARGET) $(DLIB) 30 31$(TARGET): $(OBJECTS) 32 $(COMPILER) $(CFLAGS) $(LIBS) -o $@ $^ $(LDFLAGS) 33 34$(DLIB): $(OBJECTS) 35 $(COMPILER) $(CFLAGS) -shared $^ -o $@ 36 37$(OBJDIR)/%.o: $(SRCDIR)/%.cpp 38 -mkdir -p $(OBJDIR) 39 $(COMPILER) $(CFLAGS) $(INCLUDE) $(LIBS) -o $@ -c $< 40 41$(OBJDIR)/%.o: $(SRCDIR)/%.cu 42 $(NVCC) -std=c++14 $(ARCH) $(INCLUDE) --compiler-options "$(CUFLAGS)" -c $< -o $@ 43 44# all: clean $(TARGET) 45clean: 46 -rm -f $(OBJECTS) $(DEPENDS) $(TARGET) 47-include $(DEPENDS)

sourceディレクトリ内の該当undifined
3つありますが、似通っているため
1つ目のundifinedである
「pthreadpool_compute_1d」
のコード部分を記載します。

sourceディレクトリ内
test1.cpp

void activate_array_thread(float *x, const int c, const int n, const ACTIVATION a, pthreadpool_t threadpool) { struct activate_params params = { x, n, a }; pthreadpool_compute_1d(threadpool, (pthreadpool_function_1d_t)activate_array_compute, &params, c);

includeディレクトリ内
test1.h

#ifdef NNPACK void activate_array_thread(float *x, const int c, const int n, const ACTIVATION a, pthreadpool_t threadpool); #endif

#追加
2度目のmakeファイル
コード内のLDFLAGSではコンパイルが上手くいきますが、
LDFLAGS := -lm -lgomp ./libtest.so
↑このような形でコンパイルを成功させたいです。

COMPILER = g++ CFLAGS :=-std=gnu++14 -Ofast -fPIC -fopenmp LDFLAGS := -lm -lgomp ./libtest.so /home/NNPACK/lib/libnnpack.a /home/NNPACK/lib/libpthreadpool.a /home/NNPACK/lib/libcpuinfo.a LIBS = INCLUDE = -I./ -I/usr/include TARGET = ./main SRCDIR = ifeq "$(strip $(SRCDIR))" "" SRCDIR = . endif SOURCES = $(wildcard $(SRCDIR)/*.cpp) OBJDIR = ./obj ifeq "$(strip $(OBJDIR))" "" OBJDIR = . endif OBJECTS = $(addprefix $(OBJDIR)/, $(notdir $(SOURCES:.cpp=.o))) DEPENDS = $(OBJECTS:.o=.d) all: $(TARGET) $(TARGET): $(OBJECTS) $(COMPILER) $(CFLAGS) $(LIBS) -o $@ $^ $(LDFLAGS) $(OBJDIR)/%.o: $(SRCDIR)/%.cpp -mkdir -p $(OBJDIR) $(COMPILER) $(CFLAGS) $(INCLUDE) $(LIBS) -o $@ -c $< # all: clean $(TARGET)

補足情報(FW/ツールのバージョンなど)

c++
ubuntu16.4

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

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

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

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

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

guest

回答3

0

LDFLAGSに-lpthreadpool-lpthreadの前に必要です。

これでダメならば
2度目のMakefileとやらにもLDFLAGSが必要な気がします。

投稿2018/07/10 06:45

asm

総合スコア15147

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

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

MF_19

2018/07/10 09:16

/usr/bin/ld: cannot findとなってしまうので、リンクが上手く貼れてないようでした。 シンボリックリンクで繋げようとしています。
guest

0

ベストアンサー

こんにちは。

*当然ですが1度目と2度めのmakeファイルは別物です

ちょっと意味が取れなかったのですが、makefileは通常は常に同じものを用います。
1度目と2度目で異なるmakefileを用いたのは何故でしょうか?
また、1度目に用いたmakefileを使えば正常にビルドできないでしょうか?

投稿2018/07/10 04:37

Chironian

総合スコア23272

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

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

MF_19

2018/07/10 05:34

説明不足でした。 最初のmakeファイルで.soファイルを作ります。 これを仮に外だし用(他の人に渡すため)とすると、2回目のmakeファイルは自分用にmain.cppを使って実行ファイルを作成するイメージです。 そのため、最初のmakeファイルでコンパイルは成功して.soファイルは作れています。 しかし確認用にmain.cppを記載して自分用の実行ファイルを作ろうとすると質問のエラーとなります。 つまり、.soファイルに必要なライブラリーが不足した形でコンパイルが出来てしまっている状況です。
Chironian

2018/07/10 07:00

なるほど、次のQAが関係しそうな感じがします。 https://ja.stackoverflow.com/questions/16944/linux%E3%81%A7%E3%81%AE%E5%85%B1%E6%9C%89%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 共有ライブラリBをリンクしている共有ライブラリAをmain.cppにリンクする場合、-lA -lBの両方を指定しないとリンクエラーが出るそうです。 (ところで、上記スタックオーバーフローの回答者のように詳しい手順を記述した方が的確な回答がつきやすいと思いますよ。)
MF_19

2018/07/10 07:56

はい、仰る通りですね、次回よりもう少し流れなどを明確にかくようにします。 ちなみにこれは一度目と2度目のmakeファイルにそれぞれパスを指定するのと同じことでしょうか? こちらも先にお伝えするべきでしたが、2度目のmakeファイルの LDFLAGSを下記のように指定するとコンパイルは上手くできます。 しかし、これでは外部用なので他の人も同じライブラリをインストールしていといけないと思い避けています。 もしくは私が勘違いしてしまっていますでしょうか? あまりc++を触ったことがなく、よく理解できていない部分があります。 もしこの方法で行う場合は 2度目のmakeファイルに-rpathを追加するということでしょうか? 具体的に追加の指摘頂けますと助かります。
MF_19

2018/07/10 07:59

2つめのmakeファイル内容は追加情報に上げました。
Chironian

2018/07/10 08:15

> しかし、これでは外部用なので他の人も同じライブラリをインストールしていといけないと思い避けています。 それらを使っているライブラリやアプリを使う人は当然必要になります。当該ライブラリをインストールして貰う、もしくは、MF_19さんの共有ライブラリやアプリに静的リンクするのどちらかが必要になります。 なお、これらの用語が分からなかった場合、検索すれば出てくると思いますので、検索して判らなかったら改めて質問を立てた方が好ましいです。
MF_19

2018/07/10 08:22

分かりました。ありがとうございます。 共有ライブラリの方向で確認します。
asm

2018/07/10 08:44

whole-archiveでやれそうですけど、 ライセンスの問題や ファイルサイズ肥大化の問題 あとはライブラリ使用者がpthreadpoolを使おうとした時に重複してエラーになりそうですね。 更にpthreadpoolのバージョンが異なる場合などを考えるとゾッとします。
MF_19

2018/07/10 12:45 編集

まだ解決してないですが、今回の質問は疑問点をしっかり定義できてなかったので取りやめ、別の形で質問します。 最もヒントを頂いた方をベストアンサーにさせて頂きました。
guest

0

pthreadpool_compute_1d、nnp_convolution_inference、pthreadpool_compute_2d
の3つのラベルが見つからないと言ってるんですから、それをどうにかする必要があります。

これらはどこにあるんでしょうか

投稿2018/07/10 04:05

y_waiwai

総合スコア87747

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

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

MF_19

2018/07/10 05:27

失礼しました。 それらはmakeファイル内に記載のあるincludeディレクトリ内にあります。 その中にpthreadpool.hファイルが下記のように定義してあります。 INCLUDE = -I./include
MF_19

2018/07/10 05:27

void pthreadpool_compute_1d( pthreadpool_t threadpool, pthreadpool_function_1d_t function, void* argument, size_t range);
y_waiwai

2018/07/10 05:34

それはその関数のプロトタイプ宣言ですね。 関数の本体を定義しているソースかモジュールを、コンパイル/リンクしないといけないです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問