我正在尝试使用 cmake 中的 emscripten 并生成一个 html 文件作为输出,但它不输出 html 文件。相反,它只输出一个 js 和 wasm 文件。
我包含/设置 Emscripten 工具链文件并设置
CMAKE_EXECUTABLE_SUFFIX
,但它不起作用!
CMakeLists.txt
cmake_minimum_required(VERSION 3.2.1)
set(LINK_OPTIONS)
set(CMAKE_TOOLCHAIN_FILE $ENV{EMSDK_HOME}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)
set(CMAKE_EXECUTABLE_SUFFIX ".html")
set(LINK_OPTIONS ${LINK_OPTIONS} -sWASM=1 -sALLOW_MEMORY_GROWTH=1 -sNO_EXIT_RUNTIME=0 -sASSERTIONS=1)
project(emscripten_project)
add_executable(emscripten_project main.cpp)
target_link_options(emscripten_project PUBLIC ${LINK_OPTIONS})
main.cpp
#include <iostream>
int main()
{
std::cout << "Emscripten Example\n";
return 0;
}
配置和构建命令
cmake . -G Ninja && ninja
运行
ninja -v
,给出这个:
[2/2] cmd.exe /C "cd . && C:\emsdk\upstream\emscripten\em++.bat -o emscripten_project.html -sUSE_GLFW=3 -sWASM=1 -sALLOW_MEMORY_GROWTH=1 -sNO_EXIT_RUNTIME=0 -sASSERTIONS=1 CMakeFiles/emscripten_project.dir/src/main.cpp.o -o emscripten_project.js && cd ."
重要的部分是在第一个
-o emscripten_project.js
之后有东西经过
-o emscripten_project.html
我安装的 CMake 版本是 3.25.2,
emcc
版本输出是“emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.25 (febd44b21ecaca86e2cb2a25ef3ed4a0a2076365)”
当我使用
emcmake
包装器而不是手动指定工具链文件路径时,也会出现此问题。
问题是操作顺序。 Emscripten 工具链文件做
set(CMAKE_EXECUTABLE_SUFFIX ".js")
(我将该 url 硬编码到 Emscripten 的 3.1.25 标签,因为这就是你正在使用的)。工具链文件不会立即由 CMake 获取 - 它根据需要获取它们。如果我没记错的话,它获取工具链文件的确切事件没有很好的记录(请参阅相关内容:CMake:文件解析的顺序(缓存,工具链等)?),但其中一个触发的事件采购工具链文件是对project()
命令的调用。
你做到了:
set(CMAKE_EXECUTABLE_SUFFIX ".html")
...
project(emscripten_project)
当你这样做时,你的问题就会消失:
project(emscripten_project)
...
set(CMAKE_EXECUTABLE_SUFFIX ".html")
SUFFIX
目标属性在每个目标的基础上设置可执行文件后缀。
还请注意,除了使用
set(LINK_OPTIONS ...)
,您还可以使用 the add_link_options
命令,这在“现代 CMake”中更为惯用(如果我正确理解“现代 CMake”)。
如果您正在从事一个您希望其他人而不只是您自己构建的项目,我建议您不要在您的 CMakeLists.txt 中设置
CMAKE_TOOLCHAIN_FILE
-或者至少只在未指定的情况下设置它由构建项目的人(您可以使用if(DEFINED ...)
)。作为项目维护者的礼貌是不要让用户选择他们想要如何指定 CMake 选项,这些选项旨在由他们来设置,例如工具链文件(通过使用 -DCMAKE_TOOLCHAIN_FILE=...
或--toolchain ...
)