2011-06-30 14 views
2

CMakeスクリプトを使って任意のファイルのバイト数を決定する必要がありますが、移植性があります。ファイルのサイズを決定する移植可能な方法は何ですか?

このファイルは大きいため、ファイル(READ ...)コマンドで読み込み、文字列の長さを数えることは最適ではありません。

私がMacOSやLinuxで動かすだけなら、私はちょうど私が欲しいものを与えてくれるwc -cを使っています。しかし、スクリプトはWindows互換でなければならず、Windowsツールチェーンだけを想定している必要があります。 (私はWindows開発に精通していません)

これは一般的な操作であると思っていましたが、CMakeモジュールのソースで似たものを見つけられません(間違ったことを探す可能性があります)。 cmake -Eコマンドのandyがサポートしているようです。

私は、単一のコマンドでこの情報を取得するための巧妙な方法、またはWindowsで使用できるコマンドの推奨方法を探して、if(WIN32)を条件付きで囲みます。

+1

私はあなたが、これは一般的な操作であると思うだろう理由に興味があります。 – RobertJMaynard

+0

さまざまな種類のファイルを作成および検査するために設計されたツールでは、ファイルのサイズは基本的なプロパティです。 @ sakaraの解決法には、別の基本的なプロパティである 'TIMESTAMP'サブコマンドも含まれています。 – metasim

答えて

2

FileInformationと呼ばれるCMakeモジュールがあり、ポータブルな方法でファイルのサイズを取得できます。これは、CMakeの内蔵のfileコマンドに新しいサブコマンドが追加されます。

file (SIZE filename variable) 
+0

完璧!このモジュールを共有してくれてありがとう。本当に公式のディストリビューションの一部でなければなりません。 – metasim

+0

'file()'の 'マクロ(ファイル)'のオーバーライドと使用が、すべてのCMakeコマンドで使用できる共通のパターンであるのか、それとも 'file(ファイル) ...) 'はこの機能を提供していますか?私はこれに関する文書を見つけることができない。それは非常に強力なメカニズムです。 – metasim

+1

これはCMakeメーリングリストで言及されている一般的なパターンです。 [ここ](http://www.cmake.org/pipermail/cmake/2009-October/032725.html)を参照してください。 – sakra

2

あなたがこれを好きになるかどうかはわかりませんが、私は小さなCプログラムをコンパイルして実行し、その出力を使うのが最も簡単な方法でしょう。結局のところ、何をする必要がかなりのカスタムが、C.

cmake_minimum_required(VERSION 2.8) 
project(test) 

try_run(RUN_RESULT COMPILE_RESULT ${CMAKE_CURRENT_BINARY_DIR}/bin 
    ${CMAKE_CURRENT_SOURCE_DIR}/filesize.c 
    RUN_OUTPUT_VARIABLE FILE_SIZE 
    ARGS ${CMAKE_CURRENT_SOURCE_DIR}/bigfile) 

if (NOT COMPILE_RESULT) 
    message(FATAL_ERROR "Filesize failed to compile") 
endif() 

if (RUN_RESULT EQUAL 0) 
    message(STATUS "Filesize ${FILE_SIZE}") 
else() 
    message(WARNING "Filesize failed") 
endif() 

そしてfilesize.c中で行うのは簡単です:

#include <stdio.h> 
int main(int argc, const char *argv[]) 
{ 
     FILE *fp = fopen(argv[1], "rb"); 
     if (fp != NULL) { 
       fseek(fp, 0, SEEK_END); 
       printf("%d", ftell(fp)); 
       fclose(fp); 
       return 0; 
     } 
     return 1; 
} 

COMPILE_RESULTはTRUEまたはFALSEです。ファイルが見つからない場合、try_runはエラーを返します(RUN_RESULT内)。それ以外の場合、cmakeはプログラムを実行し、ファイルの終わりまでシークし、サイズをバイト単位で出力します。結果はFILE_SIZE変数に取り込まれます。

唯一の問題は、クロスコンパイルでは機能しません。その場合、try_runは何も実行しないためです。

+0

詳細なアプローチをお寄せいただきありがとうございました。また、CMakeがFly Utilitiesで作成するのにはかなり良いことを思い出してください。 @ sakraの答えは、既存の 'file()'コマンドとうまく統合されており、モジュール内にきちんとラップされているので、私は@ sakraの答えを受け入れました。これは優れた有用な答えです。 – metasim

+0

True、プラスsakraのソリューションは、クロスコンパイルされたコードではコンパイルされたコードに依存せず、プラットフォーム固有のスクリプティングを使用します(ただし、プラットフォーム固有のスクリプティングは非常に滑りやすい傾斜です)。 – richq

1

さて、あなたが行うことができます短いファイルについて:

function(get_file_size var filename) 
    file(READ "${filename}" content HEX) 
    string(LENGTH "${content}" content_length) 
    math(EXPR content_length "${content_length}/2") 
    set(${var} ${content_length} PARENT_SCOPE) 
endfunction() 

get_file_size(len "main.c") 
message(STATUS "len(main.c)=${len}") 
+1

追加料金が必要です。ファイルにセミコロンが含まれている場合は 'string(LENGTH" $ {content} "content_length)'となります。はいCMake引用は変です。 – Timmmm

関連する問題