Что такое переносимый способ в CMake для определения размера файла? - PullRequest
2 голосов
/ 30 июня 2011

Мне нужно определить количество байтов в произвольном файле с помощью сценария CMake, но переносимым способом.

Этот файл может быть большим, поэтому чтение его с помощью команды file (READ ...) и подсчет длины строки не оптимальны.

Если бы мне нужно было работать только на MacOS и / или Linux, я бы просто использовал wc -c, что дает мне именно то, что я хочу. Но сценарий должен быть совместим с Windows, предполагая только набор инструментов Windows. (Я не очень разбираюсь в разработке Windows.)

Я ожидал, что это будет обычная операция, но я не нахожу ничего похожего в источнике модулей CMake (вероятно, ищет неправильную вещь), и, похоже, он не поддерживается командой andy cmake -E.

Так что я ищу какой-нибудь умный способ получить эту информацию с помощью одной команды или рекомендацию о том, какие команды я могу использовать в Windows, и обернуть вокруг if(WIN32) условное.

Ответы [ 3 ]

3 голосов
/ 02 июля 2011

Существует модуль CMake под названием FileInformation , который позволяет вам получить размер файла в переносном виде. Он добавляет новую подкоманду во встроенную команду CMake file:

file (SIZE filename variable)
2 голосов
/ 30 июня 2011

Не уверен, понравится ли вам это, но я думаю, что компиляция и запуск небольшой 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 ничего не запускает в этом случае.

1 голос
/ 03 мая 2015

Ну, для коротких файлов вы можете сделать:

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}")
...