🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

make

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

makefile

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

Q&A

解決済

3回答

10203閲覧

Makefile: インクルード・リンクの仕方がわかりません

Ykkykk

総合スコア140

C

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

make

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

makefile

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

0グッド

0クリップ

投稿2019/11/18 06:44

Makefileを使ってビルドしてみようとしているのですが、定義されていない参照ですエラーが出てしまい、ビルドできません。。。
ディレクトリ構造は以下のようにしています。

project_dir/ └src/ ├main/main.c ├dir/http.h http.c

上記のディレクトリの中でproject_dirとsrcにMakefileを置いています。
以下のような簡単なソースコードを作成し、ビルドしてみています。

C

1/*http.h*/ 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <curl/curl.h> 6 7extern int http(char *address);

C

1/*http.c*/ 2#include "http.h" 3 4int http(char *address) 5{ 6 CURL *curl; 7 8 char adr = &address; 9 /*ここでmainから受け取ったアドレスにアクセスしたい*/ 10 11 curl = curl_easy_init(); 12 curl_easy_setopt(curl, CURLOPT_URL, "https://qiita.com/"); 13 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); 14 15 curl_easy_perform(curl); 16 17 curl_easy_cleanup(curl); 18 19 return EXIT_SUCCESS; 20}

C

1/*main.c*/ 2#include <stdio.h> 3 4#include "http.h" 5 6 7int main() 8{ 9 printf("Hello, World.\n"); 10 11 char *adr = "https://qiita.com/"; 12 int ret; 13 ret = http(adr); 14 return 0; 15}

Makefile

1/*project_dir*/ 2CC = gcc 3 4TARGET = http_object 5 6SRC_DIR = ./src/main 7 8INCLUDE_PATHS := 9 10include ./src/Makefile 11 12$(TARGET): 13 $(CC) $(INCLUDE_PATHS) $(SRC_DIR)/main.c $< -o $@

Makefile

1/*src*/ 2INCLUDE_PATHS += -I./src/dir/.

コード中のポインタ部分などもそもそも間違っていると思いますが、上記をmakeすると、

/tmp/ccVirSiH.o: 関数 `main' 内: main.c:(.text+0xf2): `http' に対する定義されていない参照です collect2: error: ld returned 1 exit status Makefile:17: recipe for target 'http_object' failed make: *** [http_object] Error 1

上記のエラーが出てビルドできない状態です。
どのようにMakefileを修正すれば良いのでしょうか。
ご教示いただけますと幸いです。よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

最終的にはcateyeさんの書かれたリンク先を読めばいいのですが、まずは愚直に書くのがいいと思いますよ。

Makefile

1httpobj: src/main.o dir/http.o 2 gcc -Wall -g src/main.o dir/http.o -o httpobj -lcurl 3 4src/main.o: src/main.c dir/http.h 5 gcc -Wall -g -c -I./dir/ src/main.c -o src/main.o 6 7dir/http.o: dir/http.c dir/http.h 8 gcc -Wall -g -c -I./dir/ dir/http.c -o dir/http.o 9 10clean: 11 rm httpobj src/main.o dir/http.o

投稿2019/11/18 10:47

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Ykkykk

2019/11/19 00:34

詳細にご回答いただきありがとうございます。 このようにすべて手打ちしていくのが先決ですね。。 例えばこのsrc/dirにソースファイルが増えていく場合もこのように手打ちしていくのでしょうか?
退会済みユーザー

退会済みユーザー

2019/11/19 00:46

もっと柔軟に書く方法がcateyeさんの書かれたリンク先にありますが、順を追って理解する方がいいと思います。 現実的な使い勝手を考えると、リンク先程度のことは知ってて当然レベルでないと、大変です。 実はリンク先よりも、もう少し柔軟に書ける方法もあります。 ただビルドツールってmake以外にもいろいろあるので、目的に依りますが、そちらを覚えた方がいいかもしれません。makeは特に古いツールなのですよ。
guest

0

main.c:(.text+0xf2): `http' に対する定義されていない参照です

リンクエラーです。http.cがリンクできていない。

SRC_DIR = ./src/main

./src/dirは何処行った?
「追記」
参考→Makefile の書き方 (C 言語)

投稿2019/11/18 09:10

編集2019/11/18 09:47
cateye

総合スコア6851

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

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

Ykkykk

2019/11/19 00:35

ご回答いただきありがとうございます。 http.cをリンクする方法がわかりませんでした。。
guest

0

変数(マクロっていうらしい...?) を動的に変更するなら、

make INCLUDE_PATHS=<パス>

みたいにしたほうが早い気がします。

例えば、
project_dir直下がカレントディレクトリだとしたら、

make INCLUDE_PATHS=-I./src/dir

として動かすとかですね。


[追記1]

私は最近cygwin上でmakefileを使い始めました。
(それまではWindowsコマンドプロンプト上でバッチファイルから...)

なので詳しいことはわかりませんが、

方法1: 上記で挙げた方法を「シェルスクリプトを介して」コンパイルする

例えば、

make INCLUDE_PATHS=-I./src/dir

とシェルスクリプト( まあ、バッチファイルでもいいけど... ) に書いて、これを介してコンパイルする。

方法2: 直接makefileに書き込む

/*project_dir*/ CC = gcc # このへんにCFLAGSなり、独自のINCLUDEパスなりを追加する TARGET = http_object SRC_DIR = ./src/main INCLUDE_PATHS := include ./src/Makefile $(TARGET): $(CC) $(INCLUDE_PATHS) $(SRC_DIR)/main.c $< -o $@

方法3: makefileを介して別のmakefileを呼び出す

この方法はやったことありませんが、参考資料の「タスク」の項目みたいに、

# ファイル名 = comile.make compile: make CFLAGS=-I./src

としておいて、

make -f compile.make

とするとか。
(うまくいくかどうかわかりませんが...)

あと、インクルードに関しては INCLUDE( いや、CFLAGSの方か? )っていう、デフォルトで用意されている変数?があるようです。
参考: リンク1
参考: リンク2

投稿2019/11/18 06:51

編集2019/11/18 07:44
BeatStar

総合スコア4962

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

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

Ykkykk

2019/11/18 06:54

ご回答いただきありがとうございます。 ご回答いただいたようにコマンドラインから行う方が良いのでしょうか? Makefileの中にそういった設定を書き込むことはできませんでしょうか。。
Ykkykk

2019/11/18 08:21

一応、project_dirのMakefileの中でインクルードしており、ヘッダファイルを認識はしているのですが、リンクすることができていないようなのです。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問