2011-06-30 26 views
2

我需要通過CMake腳本來確定任意文件中的字節數,但是需要以便攜方式。在CMake中確定文件大小的便攜方式是什麼?

該文件可能較大,因此使用文件(READ ...)讀取命令並計算字符串長度並不是最佳選擇。

如果我只需要在MacOS和/或Linux上運行,我只需要使用wc -c,這正是我想要的。但腳本需要與Windows工具鏈兼容。 (我對Windows開發不是很瞭解)。我期望這是一個常用操作,但在CMake模塊源代碼中找不到任何類似的東西(可能搜索錯誤的東西),並且它不會似乎受到cmake -E命令的支持。

所以我正在尋找一種聰明的方式來獲得這個信息與一個單一的命令,或建議我可以在Windows中使用什麼命令(S)和環繞if(WIN32)條件。

+1

我,爲什麼你會覺得這種奇怪的是一種常見的操作。 – RobertJMaynard

+0

在用於創建和檢查各種類型文件的工具中,文件的大小是一個基本屬性。 @ sakara的解決方案還包括一個'TIMESTAMP'子命令,另一個基本屬性。 – metasim

回答

2

有一個名爲FileInformation的CMake模塊,它可以讓您以便攜的方式獲取文件的大小。它增加了一個新的子命令向CMake的內置file命令:

file (SIZE filename variable) 
+0

完美!感謝分享這個模塊。真的應該是官方發行版的一部分。 – metasim

+0

我很想知道'宏(文件)'覆蓋和使用'_file()'是一種可以與所有CMake命令一起使用的常見模式,或者它只是可能的,因爲'文件...)'提供這種能力?我無法找到關於此的文檔。這是一個非常強大的機制。 – 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是真還是假。如果找不到該文件,則try_run返回一個錯誤(在RUN_RESULT中)。否則,cmake運行程序,該程序尋找文件的結尾並以字節爲單位打印大小。結果將在FILE_SIZE變量中捕獲。

唯一的問題是它不能用於交叉編譯,因爲在這種情況下try_run不會運行任何東西。

+0

感謝您提供詳細的方法,並提醒您CMake非常擅長創建實時工具。我接受了@ sakra的答案,因爲它與現有的'file()'命令很好地集成在一起,並且很好地包裝在一個模塊中。這也是一個很好且有用的答案。 – metasim

+0

的確,加上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

您需要一些額外的引用,例如'字符串(LENGTH「$ {content}」content_length)'在文件包含分號的情況下。是的,CMake引用很奇怪。 – Timmmm

相關問題