C言語:汎用のオブジェクトファイルのパス

このQ&Aのポイント
  • C言語で汎用のオブジェクトファイルのパスを指定する方法について
  • main.cで #include "fileio.h" して、関数の実体等をfileio.cに記述する場合のコンパイルについて
  • 汎用関数群を特定のディレクトリに配置する方法について
回答を見る
  • ベストアンサー

C言語:汎用のオブジェクトファイルのパス

main.cで #include "fileio.h" して、関数の実体等をfileio.cに記述する場合コンパイルについてです。 fileio.hが様々なプログラムで使う関数群の場合で、/home/hoge/mylib 以下に fileio.h と fileio.o を置いたとします。また、main.cは別ディレクトリで開発しているとします。 環境変数C_INCLUDE_PATHを設定しておけばヘッダファイルは参照できました。(main.c内で#include "fileio.h" とするだけで参照できました) makeでコンパイルしたいのですが、オブジェクトファイルはMakefile中で LIBOBJS = /home/hoge/mylib/fileio.o などとフルパスで指定しなければいけないのでしょうか? ファイル入出力関数群など、汎用的な関数をまとめてmylibに置きたいので、どこかでmylibディレクトリのパスを指定して、ファイル名(fileio.o)だけで参照できるならそうしたいのですが。 また、そもそも汎用関数群はこういうディレクトリ構造で管理したほうがいい、などというアドバイスがあればお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

汎用関数をライブラリ化するのであれば、汎用ファイルをライブラリアンでライブラリファイルに登録するのが良いでしょう。 Makefile は以下のようになります。 最終ターゲット: main.o sub1.o sub2.o ... mylib.a ...   リンクコマンド オブジェクトリスト オプションスイッチ lib : mylib.a mylib.a : fileio.o mylib.o ...   ライブラリアンコマンド ライブラリオブジェクトリスト オプションスイッチ .c.o:   コンパイルコマンド コンパイルスイッチ ... .h.o:   コンパイルコマンド コンパイルスイッチ ... リンクコマンドのオブジェクトリストには、ライブラリ mylib.a に入れないオブジェクトのみ羅列します。 リンクコマンドのオプションスイッチには、ライブラリパスの指定スイッチで mylib.a ライブラリの置き場所も指定します。 ライブラリアンコマンドのライブラリオブジェクトリストには、ライブラリ mylib.a に入れるオブジェクトのみ羅列します。 ライブラリアンコマンドのオプションスイッチには、mylib.a の生成先も指定します。 この時、fileio.h を更新すると、 fileio.o は fileio.h に依存。fileio.o が更新される mylib.a は fileio.o に依存。mylib.a が更新される 最終ターゲットは mylib.a に依存。最終ターゲットが更新される と言う訳で、無事に最終ターゲットが更新されます。 なお、依存記述で lib : mylib.a とだけ書き、実行コマンド行が無い行がありますが、これは make lib とタイプした時にライブラリ mylib.a を更新する為の物です。 Makefile に love :   echo "Angry!" とか書いておくのも楽しいです(笑)

ssaass
質問者

補足

ご丁寧な説明ありがとうございます。 > .h.o: >   コンパイルコマンド コンパイルスイッチ .. この部分は個々の開発で用いるヘッダファイルとオブジェクトファイル(例えばsub1.cとsub1.h)のコンパイルですか? (他の開発にも使う汎用関数群である)fileio.hおよびfileio.cからfileio.oを作成するルールもここに記述することになりますか?

関連するQ&A

  • C言語で型汎用性のある関数を作成したい

    C言語です。 下記のコードでは、期待した通りにメンバにアクセスできるのですが、 構造体のメンバが多くなったとき、構造体をネストしているときには、 挙動がおかしく(なにか別の値をとりだしてしまっている?)なります。 どのようにしたら型汎用のある関数を書くことができるでしょうか? (C++ならば、汎用(テンプレート)関数があるけれども。。。) #include <stdio.h> struct hanyo{ int i; }; struct aaa{ int i; long l; char str[100]; }; struct bbb{ int i; }; void hoge(hanyo *ph){ printf("%d\n", ph->i); return; } int main(){ aaa a; a.i = 1; bbb b; b.i = 2; hoge((hanyo *)&a); hoge((hanyo *)&b); return 0; } ----実行結果---- 1 2 続行するには何かキーを押してください . . .

  • C言語のPathFileExistsについて

    visual studio 2010、C言語でPathFileExistsを使って ファイル有無のチェックをしようと試みましたが、 コンパイルエラーになってしまいました。 環境はwindowsXP、SP3です。 参考にしたいくつかのサイトでは、visual studio 2010ではPathFileExistsを使って ファイル有無をチェックできると書いてあったのですが、 visual studio 2010でもC言語だとPathFileExistsは使えないのでしょうか? TEST.C #include <stdio.h> #include <shlwapi.h> int main() {   char path[128];   sprintf( path, "c:\\tmp.txt" );   if ( PathFileExists(path) ){     printf("ファイル有\n");   }   else{     printf("ファイル無\n");   }   return 0; } TEST.OBJ : error LNK2019: 未解決の外部シンボル __imp__PathFileExistsA@4 が関数 _ main で参照されました。 TEST.EXE : fatal error LNK1120: 外部参照 1 が未解決です。 NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 10.0\VC\BI N\link.exe"' : リターン コード '0x460' Stop.

  • c:\プロジェクト別\c言語\c-master\kadai22\main.c(1) : fatal error C1083: include ファイルを開けませ

    こんにちは。 visualC++2008で、Cのプログラムを作っています。 Windowsアプリケーションです。 Mainのソースでincludeファイルkadai.hをinclude "kadai.h"として インクルードしたいのですが、できません。 ツール→オプション→プロジェクト及びソリューション→VCC++ディレクトリにkadai.hがあるディレクトリを示しても、解決できません。 どうしたらよいでしょうか?プロジェくとウィンドうの、includeにも既存のファイルを追加するで,kadai.hを追加しています。 さっぱり手立てがないので、何か足りないことがあれば教えて下さい。

  • インクルードパスを相対パスで指定

    Visual C++ 2017を使用したプロジェクト開発で、次のようなディレクトリ構造になっているとします。 root/  └ dev/    └ L1/      ├ L2/      │ ├ L3/      │ │ └ L4/      │ │   └ MyProj(開発用ディレクトリ)      │ └ foo/      │      └ include/ プロジェクトファイルやソースファイルは全てMyProjの直下にあります。 L2と同じ階層にあるincludeディレクトリにあるtest.hをソースファイルにインクルードするために、次のような#include文を記述します。 #include "../../../include/test.h" これで問題なくコンパイルが通ります。 次に、プロジェクトのプロパティの「追加のインクルードディレクトリ」に"../../foo"を追加します。 これは次のようなオプションと解釈されてコンパイラに渡されます。 /I"../../foo" fooというディレクトリのみを参照パスに追加するつもりで、プロジェクトファイルからの相対パスで指定しました。 さてここで#include文を次のように書き換えてみました。 #include "../../include/test.h" これでコンパイルが通るのです。 ソースファイルからtest.hへの相対パスは ../../../include/test.h のはずですが、なぜこれでコンパイルが通るのでしょうか? ちなみに「追加のインクルードディレクトリ」に何も指定しない状態では、includeファイルを開けないと出てコンパイルエラーとなります。 なのでこの設定が影響しているのだとは思いますが。

  • linuxにおけるCの自作ヘッダファイル

    現在C言語のしっかりと学ばなかった部分を学習したいと思い、自作ヘッダファイルの作成を勉強しています。 そこで、書籍のその章を一通り読んだあと、自分で簡単なものを作成してみましたが、エラーが出てうまくいきません。 どうしてかわかる方いたら教えてください。 コード *****main.c***** #include "print.h" int main(void) { print(); return 0; } *****print.c***** #include <stdio.h> void print(void) { printf("test\n"); } *****print.h***** extern void print(void); エラー /tmp/ccH551c1.o: In function `main': /home/ユーザ名/Documents/StudyC/main.c:5: undefined reference to `print' collect2: ld returned 1 exit status CentOS6.6にて端末上での実行です。 自分の解釈では、""でincludeすることでカレントディレクトリから目的のヘッダファイルを見つけ出してインクルードする、また、ヘッダファイル内でexternすることによってprint.cから目的の関数を定義しているので、main.cでは問題なく使えると思っています。 しかし、エラーではprint()が定義されていないと出るのでまったくわかりません・・・。

  • インクルードファイルからの相対パス

    main.php: <?php include('x/sub.php'); ....... ?> x/sub.php: <?php $a=file('data.txt'); ....... ?> において data.txt は main.php と同じディレクトリになければなりません インクルードされたファイルからファイルを呼び出すときに インクルード先からの相対パスでファイルを指定できるようにできないでしょうか? つまり上の場合にはdata.txtがsub.phpと同じディレクトリにあるようにです

    • ベストアンサー
    • PHP
  • C言語 配列挿入

    失礼します。カンマ区切りのC言語を配列に挿入したいのですが、エラーが出てしまいます。 初心者的な質問で申し訳ございませんが、よろしくお願いします。 途中までですが、コードを掲載させていただきます。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include<string.h> #define piyo 11 #define hoge 2900 int main(void) { FILE *fp; char test[piyo][hoge]; char buf[hoge]; char *ary[hoge]; int i, k; test[piyo][hoge] = NULL; if ((fp = fopen("testfile.csv", "r")) == NULL) { printf("\aファイルをオープンできません\n"); }else{ while (fgets(buf, hoge, fp) != NULL) { for (k = 0; k < hoge; k++) { ary[k] = strtok(buf, ","); } } fclose(fp); return(0); } エラーメッセージ 警告 C4047 '=': 間接参照のレベルが 'char' と 'void *' で異なっています。 C1075 左側の 中かっこ '{' に対応するものがファイルの最後まで検出されませんでした。

  • C言語に関する質問です。

    以下のプログラムはどこか間違っていますか?エラーが出ます。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー エラー csvyomikomi.c: In function ‘main’: csvyomikomi.c:10:5: warning: assignment makes pointer from integer without a cast [enabled by default] fp = fileopen(filename,"r"); ^ /tmp/ccMQWsTE.o: 関数 `main' 内: csvyomikomi.c:(.text+0x21): `fileopen' に対する定義されていない参照です csvyomikomi.c:(.text+0x8d): `fileclose' に対する定義されていない参照です collect2: error: ld returned 1 exit status ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー ソース #include <stdio.h> #include <stdlib.h> int main(void){ int a,b,c; char *filename="data01.dat"; FILE *fp; fp = fileopen(filename,"r"); if (fp == NULL){ fprintf(stderr,"%sのオープンに失敗しました。\n",filename); exit(1); } //csvファイルの読み込み fscanf(fp,"%d,%d,%d",&a,&b,&c); fileclose(fp); printf("%d,%d,%d\n",a,b,c); return 0; }

  • C言語でヘッダファイルにグローバル変数を宣言する

    main.hに static int a; と記述し、main.cで #include "main.h" [省略] a=10; のように使用して、-Wallをつけてコンパイルすると、main.cで使用しているにも関わらず、 'a' defined but not used という警告が表示されます。 同様に、関数においても、ヘッダファイルでstaticをつけると ‘~’ declared ‘static’ but never defined と警告されます。 静的グローバル変数などは、ソースファイル内で宣言しなければいけないのでしょうか?ヘッダファイル内で宣言しても警告が出ないような方法はありますか?

  • C言語の電卓におけるincludeについて

    C言語の電卓におけるincludeについて C言語の電卓におけるincludeについて質問です。 プログラミング言語C第2版 ANSI規格準拠 B.W.カーニハン・D.M.リッチー著 質問1. 4章にある電卓プログラムですが、getch.cがcalc.hをincludeしないのはなぜですか? 解説よろしくお願いします calc.h #difine NUMBER '0' main.c #include <stdio.h> #include <stdlib.h> #include "calc.h" #difine MAXOP 100 getop.c #include <stdio.h> #include <ctype.h> #include "calc.h" stack.c #include <stdio.h> #include "calc.h" #difine MAXVAL 100 getch.c #include <stdio.h> 質問2. 第4章までしか読んでいませんが、「関数で返さない値はゴミ(garbage)になる」と書いていました。 関数で返さない値は、関数から抜けると消えるものと思っていたので驚きました。 関数で返さない値の後処理はどうすればいいのですか? 質問3. 外部変数と静的変数の違いは? ―メモ― 局所変数 自動変数     main内の変数     int x;                          static int x; 永久的なメモリが与えられることを意味する 外部変数          main外の変数     static int x; 静的変数          関数内の変数     static int x; レジスタ変数        変数をレジスタに置く register int x; 以上、有識者の方、教えてくださいmm

専門家に質問してみよう