1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows11 の VSCode+Emscripten で wasm によるハローワールド (18)

Last updated at Posted at 2025-10-22

すべての記事

依存するファイルの管理を自動化

以前の記事 では JavaScript のコードで依存するデータ・ファイルを取得し管理した。

ここでは、--preload-file オプションを使いデータ・ファイルの管理を自動化する。

以下は実装したファイルの一覧となる。

C:\wasm\project\15-preload-file\.vscode\launch.json

{
    "version": "0.2.0",
    "configurations": [

        {
            "type": "chrome",
            "request": "launch",
            "name": "localhost:8080",
            "url": "http://localhost:8080/",
        }
    ]
}

C:\wasm\project\15-preload-file\CMakePresets.json

{
  "version": 5,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "wasm-config",
      "hidden": true,
      "generator": "Ninja Multi-Config",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_CXX_STANDARD": "17",
        "CMAKE_CXX_STANDARD_REQUIRED": "ON",
        "CMAKE_CXX_EXTENSIONS": "OFF",
        "CMAKE_TOOLCHAIN_FILE": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
        "CMAKE_CONFIGURATION_TYPES": "Debug;Release"
      }
    },
    {
      "name": "wasm-config-debug",
      "inherits": "wasm-config",
      "cacheVariables": {
      }
    },
    {
      "name": "wasm-config-release",
      "inherits": "wasm-config",
      "cacheVariables": {
      }
    }
  ],
  "buildPresets": [
    {
      "name": "wasm-build-debug",
      "configurePreset": "wasm-config-debug",
      "verbose": true,
      "configuration": "Debug"
    },
    {
      "name": "wasm-build-release",
      "configurePreset": "wasm-config-release",
      "verbose": true,
      "configuration": "Release"
    }
  ]
}

C:\wasm\project\15-preload-file\CMakeLists.txt
-- --preload-file では「実際のパス @ 仮想ファイルシステム上のパス」の形式で指定

cmake_minimum_required(VERSION 3.20)
project(15_preload_file LANGUAGES CXX)

add_executable(15_preload_file main.cpp)

target_link_options(15_preload_file PRIVATE
    $<$<CONFIG:Debug>:-gsource-map -sASSERTIONS=1 -sSAFE_HEAP=1>
    "-sEXPORTED_RUNTIME_METHODS=FS"
    "-sEXPORT_ES6=1"
    "--preload-file=${CMAKE_SOURCE_DIR}/data.txt@data.txt"
)

C:\wasm\project\15-preload-file\index.html

  • データ・ファイルの fetch() などは不要
  • .data の位置を locateFile() でグルーコードに伝える必要がある
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8"/>
        <script type="module">
            import Module from './build/Debug/15_preload_file.js';

            let v = 0;

            const monitorRunDependencies = left => console.log(`left ${left}`);

            const locateFile = (path, prefix) => {
                if (path.endsWith(".data")) {
                    return './build/Debug/' + path;
                }

                return prefix + path;
            };

            Module({ arguments: ['data.txt'], monitorRunDependencies, locateFile }).then(emsModule =>
            {
                v = emsModule._increment(v);
                console.log(`return=${v}`);
            });
        </script>
    </head>
    <body>
    </body>
</html>

C:\wasm\project\15-preload-file\data.txt

1000
1010
2100

C:\wasm\project\15-preload-file\main.cpp

// UTF-8N CRLF
#include <emscripten.h>
#include <iostream>
#include <fstream>

extern "C"
EMSCRIPTEN_KEEPALIVE
int increment(int v)
{
	printf("-- increment(%d)\n", v);
	return v + 1;
}

int main(int argc, char** argv)
{
	std::cout << "C++ main(argc=" << argc << ", argv=[";

	for (int i=0; i<argc; ++i)
	{
		if (i) {
			std::cout << ",";
		}
		std::cout << "'" << argv[i] << "'";
	}

	std::cout << "])" << std::endl;

	std::cout << "open: " << argv[1] << std::endl;
	std::ifstream ifs{ argv[1] };
	if (ifs)
	{
	    std::string line;
    	while (std::getline(ifs, line))
		{
	        std::cout << "DATA: " << line << std::endl;
    	}
	}
	else
	{
		std::cerr << "file open error" << std::endl;
	}

	return 0;
}

// EOF

ビルド後の確認

--preload-file で指定したファイルは *.data としてまとめられ wasm ファイルと同じディレクトリに配置され、実行時に locateFile() により解決したパスから自動的に取得される。

C:\wasm\project\15-preload-file>dir build\Debug\*.data
 ドライブ C のボリューム ラベルは OS です
 ボリューム シリアル番号は E886-5372 です

 C:\wasm\project\15-preload-file\build\Debug のディレクトリ

2025/10/22  10:50                16 15_preload_file.data
               1 個のファイル                  16 バイト
               0 個のディレクトリ  623,659,319,296 バイトの空き領域

実行結果

monitorRunDependencies() での監視を含め、手動でファイル管理をしていたものと結果に変わりはない。

left 1
left 2
left 1
left 0
C++ main(argc=2, argv=['./this.program','data.txt'])
open: data.txt
DATA: 1000
DATA: 1010
DATA: 2100
-- increment(0)
return=1

似たオプションに --embed-file があるが、こちらはビルド時にファイルをグルーコードに埋め込む。

次回 は One True Awk を wasm として動かしてみる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?