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

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

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

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

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

Q&A

解決済

2回答

3105閲覧

makefile:別階層のヘッダファイルが読み込めません。

naony

総合スコア2

makefile

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

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

0グッド

0クリップ

投稿2021/05/09 10:55

編集2021/05/09 11:24

前提・実現したいこと

Macのターミナル上でmakefileを用いてコンパイルしたい。
makefileと同じ階層に.cpp,.hファイルがあれば実行できたが、
.hファイルを別の階層に置くとよくわからないメッセージが出る。
ここに質問の内容を詳しく書いてください。
makefileの勉強をしていて、makefileとソースコードが別のディレクトリにあるときの書き方を勉強しています。
includeパスの記述を行っても変なエラーが出て全く読めません。
ディレクトリ構成は

イメージ説明

です。

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

MacBook-Pro:make_practice user$ make c++ -I./mylib -c -o main.o src/main.cpp c++ -I./mylib -c -o mylib.o src/mylib.cpp g++ -o hello main.o mylib.o Undefined symbols for architecture x86_64: "__ZNKSt3__16locale9use_facetERNS0_2idE", referenced from: __ZNSt3__1L9use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE in mylib.o "__ZNKSt3__18ios_base6getlocEv", referenced from: __ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc in mylib.o "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc", referenced from: __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2Emc in mylib.o "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev", referenced from: __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_ in mylib.o "__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE3putEc", referenced from: __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_ in mylib.o "__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5flushEv", referenced from: __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_ in mylib.o "__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_", referenced from: __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m in mylib.o "__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev", referenced from: __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m in mylib.o "__ZNSt3__14coutE", referenced from: __Z5hellov in mylib.o "__ZNSt3__15ctypeIcE2idE", referenced from: __ZNSt3__1L9use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE in mylib.o "__ZNSt3__16localeD1Ev", referenced from: __ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc in mylib.o "__ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv", referenced from: __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m in mylib.o "__ZNSt3__18ios_base5clearEj", referenced from: __ZNSt3__18ios_base8setstateEj in mylib.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status make: *** [hello] Error 1

該当のソースコード

CC = g++
VPATH = src
CPPFLAGS = -I./mylib
objects = main.o mylib.o
headers = mylib.h
output = hello

$(output) : $(objects)
$(CC) -o $@ $?
%.o : %.cpp $(headers)
$(CC) -c -o $@ $<
.PHONY: clean
clean:
rm -f $(output) $(objects)

makefile

該当のソースコード

include "mylib.h"

int main(void)
{
hello();
return 0;
}

c++

該当のソースコード

include<iostream>
include"mylib.h"

int hello(void)
{
std::cout << "Hello" << std::endl;
return 0;
}

c++

該当のソースコード

ifndef MYLIB_H
define MYLIB_H

int hello(void);

endif

ヘッダー

試したこと

CPPFLAGSをCFLAGSに変えて書いたりしました。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

headers = mylib.hheaders = mylib/mylib.hに変えないといけないのでは?

投稿2021/05/09 11:04

itagagaki

総合スコア8402

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

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

naony

2021/05/09 11:25

変えたら以下のようなエラーが出ました。。。 MacBook-Pro:make_practice naony$ make g++ -c -o main.o src/main.cpp src/main.cpp:1:10: fatal error: mylib.h: No such file or directory 1 | #include "mylib.h" | ^~~~~~~~~ compilation terminated. make: *** [main.o] Error 1
itagagaki

2021/05/10 12:15 編集

それは `#include "../mylyb/mylib.h"`に変更しないといけないのでは。
pepperleaf

2021/05/09 11:36

ソースのパスまで変えたら、コンパイルオプション '-I' の 意味が無いのでは? make -n とするとどうなるのでしょう? (実行せずに、コマンドラインのみ出力)
y_waiwai

2021/05/09 11:40

make使わないでそれを直接実行させてみたらどうなります?
itagagaki

2021/05/09 12:07 編集

pepperleaf さん パターンルール %.o : %.cpp $(headers) $(CC) -c -o $@ $< で -I を指定していないので、今回それは関係ないですね。
pepperleaf

2021/05/09 12:13

CPPFLAGS は自動適用されてなかった? (仕様未確認)
itagagaki

2021/05/09 12:15

それは暗黙ルールの場合では ここではmakefileにパターンルールを明示的に書いているので暗黙ルールが適用されていないと思います。
itagagaki

2021/05/09 12:18

おそらく最初に g++ ではなく c++ が使われているのはパターンルールではなく暗黙ルールが適用されているからで、その暗黙ルールでは -I が適用されていますね。
pepperleaf

2021/05/09 12:36

暗黙ルールの c++が使われてるという事は、その箇所でも不適切という事ですね。(多分)
itagagaki

2021/05/09 12:47

発生しているエラーはリンクエラーで、これはおそらく、暗黙ルールが適用されてしまって c++ で生成された .o を g++ でリンクしているから。 パターンルール %.o : %.cpp $(headers) が今までは期待通り適用されて g++ でコンパイルされていたのが、mylib.h を移動したことでこのルールから外れてしまったわけで(なぜなら $(headers) が無いから)、このルールに引き戻すためには、headers = mylib/mylib.h でなければならないわけです。 で、めでたく期待するパターンルールで g++ でコンパイルされるように戻ったんだけど、この生成ルールでは -I は指定していないので、#include "mylib.h" はエラーになる。なので、それは #include "../mylib/mylib.h" にしなければならないということです。生成ルールのほうに -I を加える手もありますけどね。
naony

2021/05/10 11:22

返信が遅くなり申し訳ございません。 パターンルールの認識が曖昧になっていることがわかりました。 生成ルールのについても知識がなく、今回の場合ソースコードのインクルード先を変更せずにmakefileの記述を変更するとしたらどのように変更すればよいでしょうか?
itagagaki

2021/05/10 12:12

*.cppコードのコンパイルは、 %.o : %.cpp $(headers) $(CC) -c -o $@ $< このルールで行っていますね。上でも触れましたが、このときコンパイラ(g++)に -I オプションでincludeパスを指定することができます。ちょうど CPPFLAGS = -I./mylib が設定されていますね(役に立っていなかったけど)。このマクロを使って、 %.o : %.cpp $(headers) $(CC) -c -o $@ $(CPPFLAGS) $< こうすれば、g++ は、#include "mylib.h" で、まずカレントディレクトリの mylib.h を探し、見つからなかったら ./mylib/mylyb.h を探します。 なお #include <mylib.h> の場合は、カレントディレクトリは探しません。 あと、今気づきましたが、 $(output) : $(objects) $(CC) -o $@ $? これだと $(objects) の中で $(output) よりタイムスタンプが新しいものだけしかリンクされないことになるのでダメです。正しくは $(CC) -o $@ $^ ですね。$? $^ $< $@ などの意味は調べてみてください。
naony

2021/05/10 20:58

コンパイルできました! $?とかの意味もちゃんと調べてみます。 皆さんありがとうございました!
guest

0

ところで、相対アドレスでインクルードディレクトリを指定されているようですが、
C++というコマンドのカレントディレクトリってどこだとお思いでしょうか

投稿2021/05/09 11:48

y_waiwai

総合スコア87774

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

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

naony

2021/05/10 11:12

ターミナル上で cd ./xxx/ で指定したディレクトリでしょうか?
naony

2021/05/10 11:13

返信が遅くなり申し訳ございません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問