ccacheをarmccに対応させてみる 03

できた。ばんざい!

なんかdistccも同じような変更でできそうなきがしてきたぞ。

差分のパッチを作ってみようとおもったら、cygwinには入ってないのですね

以下、差分。
ccache-2.4.tar.gz の ccache.c の変更だけで済みました。

--- ccache.c.org	2004-09-13 19:38:30.000000000 +0900
+++ ccache.c	2008-05-14 12:58:37.362287300 +0900
@@ -2,6 +2,7 @@
   a re-implementation of the compilercache scripts in C
 
   The idea is based on the shell-script compilercache by Erik Thiele <erikyyy@erikyyy.de>
+  ccacheのアイディアはErik Thiele氏のシェルスクリプトコンパイラキャッシュに基づいてます
 
    Copyright (C) Andrew Tridgell 2002
    Copyright (C) Martin Pool 2003
@@ -24,77 +25,110 @@
 #include "ccache.h"
 
 /* the base cache directory */
+// キャッシュの基本ディレクトリ
 char *cache_dir = NULL;
 
 /* the directory for temporary files */
+// 一時ファイル置き場ディレクトリ
 static char *temp_dir = NULL;
 
 /* the debug logfile name, if set */
+// デバック用ログファイル名
 char *cache_logfile = NULL;
 
 /* the argument list after processing */
+// 引数リスト(after processingってのがなんの処理の後なのかは不明)
 static ARGS *stripped_args;
 
 /* the original argument list */
+// オリジナル引数リスト(引数で受け取ったまんまの形ってことだね)
 static ARGS *orig_args;
 
 /* the output filename being compiled to */
+// 出力ファイル名
 static char *output_file;
 
 /* the source file */
+// ソースファイル名
 static char *input_file;
 
 /* the name of the file containing the cached object code */
+// キャッシュされたオブジェクトコードを含んでいるファイルの名前
 static char *hashname;
 
 /* the extension of the file after pre-processing */
+// プリプロセスされたあとのファイルの拡張子
 static const char *i_extension;
 
 /* the name of the temporary pre-processor file */
+// プリプロセスしたファイルの一時的なファイル名
 static char *i_tmpfile;
 
 /* are we compiling a .i or .ii file directly? */
+// 拡張子.i / .iiのファイルをダイレクトにコンパイルするかい?
 static int direct_i_file;
 
 /* the name of the cpp stderr file */
+// 標準エラー出力(stderr)を書き出すファイル名
 static char *cpp_stderr;
 
 /* the name of the statistics file */
+// 統計ファイルの名前
 char *stats_file = NULL;
 
 /* can we safely use the unification hashing backend? */
+// 問題なくバックエンドの統一ハッシュを使うことができるか?
 static int enable_unify;
 
 /* a list of supported file extensions, and the equivalent
    extension for code that has been through the pre-processor
 */
+// サポートする拡張子とプリプロセス後の拡張子のリスト
+// armccは拡張子が cとかcppじゃないと、ソースだと認識してくれない
 static struct {
 	char *extension;
 	char *i_extension;
 } extensions[] = {
-	{"c", "i"},
-	{"C", "ii"},
+	{"c", "C"},
+	{"C", "C"},
 	{"m", "mi"},
-	{"cc", "ii"},
-	{"CC", "ii"},
-	{"cpp", "ii"},
-	{"CPP", "ii"},
-	{"cxx", "ii"},
-	{"CXX", "ii"},
-	{"c++", "ii"},
-	{"C++", "ii"},
+	{"cc", "CPP"},
+	{"CC", "CPP"},
+	{"cpp", "CPP"},
+	{"CPP", "CPP"},
+	{"cxx", "CPP"},
+	{"CXX", "CPP"},
+	{"c++", "CPP"},
+	{"C++", "CPP"},
 	{"i", "i"},
 	{"ii", "ii"},
 	{NULL, NULL}};
+// 	{"c", "i"},
+// 	{"C", "ii"},
+// 	{"m", "mi"},
+// 	{"cc", "ii"},
+// 	{"CC", "ii"},
+// 	{"cpp", "ii"},
+// 	{"CPP", "ii"},
+// 	{"cxx", "ii"},
+// 	{"CXX", "ii"},
+// 	{"c++", "ii"},
+// 	{"C++", "ii"},
+// 	{"i", "i"},
+// 	{"ii", "ii"},
+// 	{NULL, NULL}};
 
 /*
   something went badly wrong - just execute the real compiler
 */
+// 解析不能になるほど重大エラーが発生した場合、
+// 本物のコンパイラを実行する
 static void failed(void)
 {
 	char *e;
 
 	/* delete intermediate pre-processor file if needed */
+	// 必要ならプリプロセス後の中間ファイルを削除する(*.i/*.iiのやつ)
 	if (i_tmpfile) {
 		if (!direct_i_file) {
 			unlink(i_tmpfile);
@@ -104,6 +138,7 @@
 	}
 
 	/* delete the cpp stderr file if necessary */
+	// 必要なら標準エラー出力(stderr)ファイルを削除する
 	if (cpp_stderr) {
 		unlink(cpp_stderr);
 		free(cpp_stderr);
@@ -111,20 +146,25 @@
 	}
 
 	/* strip any local args */
+	// ccache用の引数を削る
+	// "--ccache-"から始まっている引数を削る
 	args_strip(orig_args, "--ccache-");
 
-	if ((e=getenv("CCACHE_PREFIX"))) {
-		char *p = find_executable(e, MYNAME);
+	// 環境変数CCACHE_PREFIX があれば、引数リストの先頭に その中身を を追加
+	// まぁ"distcc"のことなんだろうけど
+	if ((e=getenv("CCACHE_PREFIX"))) {			// 環境変数CCACHE_PREFIX取得。distccを指定したりする
+		char *p = find_executable(e, MYNAME);	// eのなかから実行ファイル名を検出。MYNAMEは除く。ちなみに MYNAME="ccache"
 		if (!p) {
 			perror(e);
 			exit(1);
 		}
 		args_add_prefix(orig_args, p);
 	}
-
+	
+	//実行
 	execv(orig_args->argv[0], orig_args->argv);
 	cc_log("execv returned (%s)!\n", strerror(errno));
-	perror(orig_args->argv[0]);
+	perror(orig_args->argv[0]);	// システムエラーメッセージを出力する
 	exit(1);
 }
 
@@ -132,10 +172,12 @@
 /* return a string to be used to distinguish temporary files 
    this also tries to cope with NFS by adding the local hostname 
 */
+// 一時ファイル名を返す
+// ファイル名にホスト名も足すことによってNFS(Network File System)にも対応している
 static const char *tmp_string(void)
 {
 	static char *ret;
-
+	
 	if (!ret) {
 		char hostname[200];
 		strcpy(hostname, "unknown");
@@ -143,14 +185,61 @@
 		gethostname(hostname, sizeof(hostname)-1);
 #endif
 		hostname[sizeof(hostname)-1] = 0;
-		asprintf(&ret, "%s.%u", hostname, (unsigned)getpid());
+		asprintf(&ret, "%s.%u", hostname, (unsigned)getpid());	// getpid() = プロセス ID を得る
 	}
 
 	return ret;
 }
 
 
+//*********************************************************
+// 文字列 String を nShift だけ移動する。
+// 移動先へのポインタを返す。
+//*********************************************************
+char *StrShift( char *String, size_t nShift )
+{
+	char *start = String;
+	char *stop  = String + strlen( String );
+	memmove( start + nShift, start, stop-start+1 );
+
+	return String + nShift;
+}//StrShift
+
+//*********************************************************
+// 文字列 String の文字列 From を文字列 To で置換する。
+// 置換後の文字列 String のサイズが String の記憶領域を超える場合の動作は未定義。
+//*********************************************************
+char *StrReplace( char *String, const char *From, const char *To )
+{
+	int   nToLen;   // 置換する文字列の長さ
+	int   nFromLen; // 検索する文字列の長さ
+	int   nShift;
+	char *start;    // 検索を開始する位置
+	char *stop;     // 文字列 String の終端
+	char *p;
+
+	nToLen   = strlen( To );
+	nFromLen = strlen( From );
+	nShift   = nToLen - nFromLen;
+	start    = String;
+	stop     = String + strlen( String );
+
+	// 文字列 String の先頭から文字列 From を検索
+	while( NULL != ( p = strstr( start, From ) ) )
+	{
+		// 文字列 To が複写できるようにする
+		start = StrShift( p + nFromLen, nShift );
+		stop  = stop + nShift;
+
+		// 文字列 To を複写
+		memmove( p, To, nToLen );
+	}
+
+	return String;
+}//StrReplace
+
 /* run the real compiler and put the result in cache */
+// リアルコンパイラ(実際にコンパイルするコンパイラ)を実行し、結果をキャッシュに置く
 static void to_cache(ARGS *args)
 {
 	char *path_stderr;
@@ -162,7 +251,11 @@
 	x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string());
 	x_asprintf(&tmp_hashname, "%s/tmp.hash.%s.o", temp_dir, tmp_string());
 
+	// 引数リストにに -o と出力ファイル名を足してる
 	args_add(args, "-o");
+	// 置換 '/' -> '\'
+	tmp_hashname = StrReplace(tmp_hashname,"/","\\");
+	//x_asprintf(&tmp_hashname, "\"%s\"", tmp_hashname);
 	args_add(args, tmp_hashname);
 
 	/* Turn off DEPENDENCIES_OUTPUT when running cc1, because
@@ -171,16 +264,25 @@
 	 *  tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
 	 *
 	 * unsetenv() is on BSD and Linux but not portable. */
+	// cc1を走らせるときには DEPENDENCIES_OUTPUT をOFFにすること。
+	// そうしないと 以下のような出力になってしまう
+	//    tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
+	// 一応 unsetenv() という関数がBSDとlinuxにあるが、使うと移植性が悪い
 	putenv("DEPENDENCIES_OUTPUT");
 	
 	if (getenv("CCACHE_CPP2")) {
-		args_add(args, input_file);
+		input_file = StrReplace(input_file,"/","\\");
+		//x_asprintf(&input_file, "\"%s\"", input_file);	// "(ダブルクォーテーション)でくくるならこっち
+		args_add(args, input_file);	// ソースファイル名そのものを引数リストに追加
 	} else {
-		args_add(args, i_tmpfile);
+		i_tmpfile = StrReplace(i_tmpfile,"/","\\");
+		//x_asprintf(&i_tmpfile, "\"%s\"", i_tmpfile);	// "(ダブルクォーテーション)でくくるならこっち
+		args_add(args, i_tmpfile);	// プリプロセスしたファイルの一時的なファイル名を引数リストに追加
 	}
-	status = execute(args->argv, tmp_stdout, tmp_stderr);
-	args_pop(args, 3);
+	status = execute(args->argv, tmp_stdout, tmp_stderr);	// コンパイル実行
+	args_pop(args, 3);	// 引数リストから、末尾3つ削除。つまり、このAPIで追加した "-o" "出力ファイル名" "ソースファイル名"を削除ということ
 
+	// 標準出力(stdout)ファイルから情報がとれない or とれたけど ファイルサイズが0じゃない
 	if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
 		cc_log("compiler produced stdout for %s\n", output_file);
 		stats_update(STATS_STDOUT);
@@ -192,19 +294,26 @@
 	unlink(tmp_stdout);
 
 	if (status != 0) {
+		// 失敗だった場合
+		
 		int fd;
 		cc_log("compile of %s gave status = %d\n", output_file, status);
-		stats_update(STATS_STATUS);
+		stats_update(STATS_STATUS);	// 統計情報カウンタ++
 
 		fd = open(tmp_stderr, O_RDONLY | O_BINARY);
 		if (fd != -1) {
+			// 標準エラー出力が無かった場合
+			
+			// 出力ファイルパスに "/dev/null" があるか
+			// ファイル名の変更に成功した場合
+			// ENOENT = "No such file or directory" つまりファイルがみつからないエラーだった場合
 			if (strcmp(output_file, "/dev/null") == 0 ||
 			    rename(tmp_hashname, output_file) == 0 || errno == ENOENT) {
 				if (cpp_stderr) {
 					/* we might have some stderr from cpp */
 					int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY);
 					if (fd2 != -1) {
-						copy_fd(fd2, 2);
+						copy_fd(fd2, 2);	// コンパイラが出した標準エラー出力ファイルの内容をコピー。2はたぶん標準エラー出力をさしてるんだと思う。つまり、ファイルの中のエラーをターミナルに出力してるんだろう
 						close(fd2);
 						unlink(cpp_stderr);
 						cpp_stderr = NULL;
@@ -213,30 +322,31 @@
 
 				/* we can use a quick method of
                                    getting the failed output */
-				copy_fd(fd, 2);
+				copy_fd(fd, 2);	// 標準エラー出力ファイルの内容をコピー。2はたぶん標準エラー出力をさしてるんだと思う。つまり、ファイルの中のエラーをターミナルに出力してるんだろう
 				close(fd);
 				unlink(tmp_stderr);
 				if (i_tmpfile && !direct_i_file) {
 					unlink(i_tmpfile);
 				}
-				exit(status);
+				exit(status);	// 終了
 			}
 		}
 		
 		unlink(tmp_stderr);
 		unlink(tmp_hashname);
-		failed();
+		failed();	// ccacheに失敗したのでリアルコンパイルする
 	}
 
 	x_asprintf(&path_stderr, "%s.stderr", hashname);
 
-	if (stat(tmp_stderr, &st1) != 0 ||
-	    stat(tmp_hashname, &st2) != 0 ||
-	    rename(tmp_hashname, hashname) != 0 ||
-	    rename(tmp_stderr, path_stderr) != 0) {
+	if (stat(tmp_stderr, &st1) != 0 ||			// ファイルから情報がとれない
+	    stat(tmp_hashname, &st2) != 0 ||		// ファイルから情報がとれない
+	    rename(tmp_hashname, hashname) != 0 ||	// リネーム失敗
+	    rename(tmp_stderr, path_stderr) != 0) {	// リネーム失敗
+		// 
 		cc_log("failed to rename tmp files - %s\n", strerror(errno));
 		stats_update(STATS_ERROR);
-		failed();
+		failed();	// ccacheに失敗したのでリアルコンパイルする
 	}
 
 	cc_log("Placed %s into cache\n", output_file);
@@ -620,6 +730,8 @@
    process the compiler options to form the correct set of options 
    for obtaining the preprocessor output
 */
+// コンパイルオプションから
+// オプションの集合を作る
 static void process_args(int argc, char **argv)
 {
 	int i;
@@ -632,13 +744,18 @@
 
 	args_add(stripped_args, argv[0]);
 
+	// コンパイルオプションの中に オプションじゃないもの ファイルとか あったらNGーみたいだな
+	
 	for (i=1; i<argc; i++) {
 		/* some options will never work ... */
+		// いくつかのオプションは永遠に処理しない・・・
+		// -Eがすでについていたら、リアルコンパイルにいく
 		if (strcmp(argv[i], "-E") == 0) {
 			failed();
 		}
 
 		/* these are too hard */
+		// これらのオプションはサポートしてない
 		if (strcmp(argv[i], "-fbranch-probabilities")==0 ||
 		    strcmp(argv[i], "-M") == 0 ||
 		    strcmp(argv[i], "-MM") == 0 ||
@@ -650,6 +767,7 @@
 		}
 
 		/* we must have -c */
+		// -c がついてないと処理しないよ
 		if (strcmp(argv[i], "-c") == 0) {
 			args_add(stripped_args, argv[i]);
 			found_c_opt = 1;
@@ -657,6 +775,8 @@
 		}
 
 		/* -S changes the default extension */
+		// -S デフォルト拡張子を変える。
+		// これがあるってことはアセンブラってことだよね
 		if (strcmp(argv[i], "-S") == 0) {
 			args_add(stripped_args, argv[i]);
 			found_S_opt = 1;
@@ -664,7 +784,9 @@
 		}
 		
 		/* we need to work out where the output was meant to go */
+		// 出力ファイル名を output_file に保存
 		if (strcmp(argv[i], "-o") == 0) {
+			// -o オプションが引数のおけつについる=出力ファイル名が無い なら不正。
 			if (i == argc-1) {
 				cc_log("missing argument to %s\n", argv[i]);
 				stats_update(STATS_ARGS);
@@ -676,6 +798,7 @@
 		}
 		
 		/* alternate form of -o, with no space */
+		// -oオプションと 出力ファイル名の間にスペースが無い場合にも対応してるよ
 		if (strncmp(argv[i], "-o", 2) == 0) {
 			output_file = &argv[i][2];
 			continue;
@@ -684,6 +807,7 @@
 		/* debugging is handled specially, so that we know if we
 		   can strip line number info 
 		*/
+		// デバックは特別に扱われる
 		if (strncmp(argv[i], "-g", 2) == 0) {
 			args_add(stripped_args, argv[i]);
 			if (strcmp(argv[i], "-g0") != 0) {
@@ -693,6 +817,7 @@
 		}
 
 		/* The user knows best: just swallow the next arg */
+		// 次のオプションを無条件で引数リストに追加する
 		if (strcmp(argv[i], "--ccache-skip") == 0) {
 			i++;
 			if (i == argc) {
@@ -703,6 +828,7 @@
 		}
 
 		/* options that take an argument */
+		// 引数付きオプション
 		{
 			const char *opts[] = {"-I", "-include", "-imacros", "-iprefix",
 					      "-iwithprefix", "-iwithprefixbefore",
@@ -710,6 +836,7 @@
 					      "-MT", "-MQ", "-isystem", "-aux-info",
 					      "--param", "-A", "-Xlinker", "-u",
 					      "-idirafter", 
+					      "-via","-fpu","-cpu",	// armcc用追加オプション 2008/05/13
 					      NULL};
 			int j;
 			for (j=0;opts[j];j++) {
@@ -848,6 +975,8 @@
 	}
 
 	/* process argument list, returning a new set of arguments for pre-processing */
+	// コンパイルオプションのリストを作る
+	// プリプロセスのために新しい引数のリストを返す
 	process_args(orig_args->argc, orig_args->argv);
 
 	/* run with -E to find the hash */
@@ -876,7 +1005,7 @@
 
 static void usage(void)
 {
-	printf("ccache, a compiler cache. Version %s\n", CCACHE_VERSION);
+	printf("ccache, a compiler cache. Version aaaaaa %s\n", CCACHE_VERSION);
 	printf("Copyright Andrew Tridgell, 2002\n\n");
 	
 	printf("Usage:\n");
@@ -981,15 +1110,17 @@
 {
 	char *p;
 
-	cache_dir = getenv("CCACHE_DIR");
-	if (!cache_dir) {
-		x_asprintf(&cache_dir, "%s/.ccache", get_home_directory());
-	}
-
-	temp_dir = getenv("CCACHE_TEMPDIR");
-	if (!temp_dir) {
-		temp_dir = cache_dir;
-	}
+ 	cache_dir = getenv("CCACHE_DIR");
+ 	if (!cache_dir) {
+ 		//x_asprintf(&cache_dir, "%s/.ccache", get_home_directory());
+ 		// 標準的なcygwinインストール先フォルダを先頭につけておく
+ 		x_asprintf(&cache_dir, "c:/cygwin%s/.ccache", get_home_directory());
+ 	}
+
+ 	temp_dir = getenv("CCACHE_TEMPDIR");
+ 	if (!temp_dir) {
+ 		temp_dir = cache_dir;
+ 	}
 
 	cache_logfile = getenv("CCACHE_LOGFILE");