CMake 中确定文件大小的可移植方式是什么?

发布于 2024-11-17 16:09:52 字数 421 浏览 2 评论 0原文

我需要通过 CMake 脚本确定任意文件中的字节数,但以可移植的方式。

该文件可能很大,因此使用 file(READ...) 命令读取它并计算字符串长度并不是最佳选择。

如果我只需要在 MacOS 和/或 Linux 上运行,我只需使用 wc -c,这正是我想要的。但假设只有 Windows 工具链,该脚本需要与 Windows 兼容。 (我对 Windows 开发不是很了解。)

我预计这是一个常见操作,但在 CMake 模块源中没有找到任何类似的内容(可能搜索错误的东西),并且它似乎不受支持由 andy 执行 cmake -E 命令。

因此,我正在寻找一些使用单个命令获取此信息的巧妙方法,或者关于我可以在 Windows 中使用哪些命令并围绕 if(WIN32) 条件的建议。

I need to determine the number of bytes in an arbitrary file via a CMake script, but in a portable manner.

This file may be large, so reading it in with the file(READ...) command and counting the string length isn't optimal.

If I only had to run on MacOS and/or Linux I'd just use wc -c, which gives me exactly what I want. But the script needs to be Windows compatible assuming only the Windows toolchain. (I'm not very knowledgeable with Windows development.)

I expected this to be a common operation, but am not finding anything similar in the CMake Modules source (likely searching for the wrong thing), and it doesn't appear to be supported by andy of the cmake -E commands.

So I'm looking for either some clever way of getting this info with a single command, or a recommendation on what command(s) I could use in Windows and wrap around a if(WIN32) conditional.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

零度° 2024-11-24 16:09:52

有一个名为 FileInformation 的 CMake 模块,它可以让您以可移植的方式获取文件的大小。它向 CMake 的内置 file 命令添加了一个新的子命令:

file (SIZE filename variable)

There is a CMake module called FileInformation which lets you obtain the size of a file in a portable way. It adds a new sub-command to CMake's built-in file command:

file (SIZE filename variable)
能怎样 2024-11-24 16:09:52

不确定您是否会喜欢这个,但我认为编译和运行一个小型 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 不会运行任何东西。

Not sure if you're going to like this, but I think compiling and running a small C program and using its output would be the easiest way to do this. After all, what you need to do is pretty custom, but easy to do in 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()

And in 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 is TRUE or FALSE. And if the file isn't found try_run returns an error (in RUN_RESULT). Otherwise cmake runs the program, which seeks to the end of the file and prints the size in bytes. The result is captured in the FILE_SIZE variable.

The only problem with this is that it won't work for cross-compilation, as try_run doesn't run anything in that case.

渡你暖光 2024-11-24 16:09:52

好吧,对于短文件,你可以这样做:

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

Well, for short files you can do:

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}")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文