我最近正在开展一个项目,其中包括 Emscripten 的使用。我可以在终端上安装并运行一些示例,但我想将其与 Clion 集成,以便我可以直接将 emscripten 包含到我的主项目中并构建它。我尝试将目录添加到
CMakeList
但在构建时出现错误。任何人都可以帮助我找到将 Emscripten 集成到 Clion 中的适当方法,或者对 CMakeList
中包含哪些内容有任何建议。任何帮助将不胜感激。谢谢您宝贵的时间。
我将这些行包含在演示项目的 CMakeList 中:
cmake_minimum_required(VERSION 3.12)
project(projectShell)
set(CMAKE_CXX_STANDARD 14)
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set(CMAKE_C_COMPILER "emcc")
endif ()
include_directories(include/rapidjson)
include_directories(/home/myfastcomp/emscripten/emscripten/system/include
)
add_executable(projectShell main.cpp library.cpp library.h)
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set_target_properties(projectShell PROPERTIES LINK_FLAGS "-o
dist/projectShell.js -s USE_FREETYPE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=1 -s SAFE_HEAP=1 --bind -s WASM=1 -O2 -s LEGACY_GL_EMULATION=0 -s GL_UNSAFE_OPTS=0 --pre-js pre-module.js --post-js post-module.js -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -s INVOKE_RUN=0 -std=c++11 -s USE_WEBGL2=1 -s FULL_ES3=1 -s USE_GLFW=3 -s OFFSCREENCANVAS_SUPPORT=1 --preload-file textures --preload-file shaders --preload-file fonts")
endif()
错误如下:
In file included from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_config.h:45:0,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_stdinc.h:31,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_main.h:25,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL.h:72,
from /home/myfastcomp/emscripten/emscripten/system/include/emscripten/emscripten.h:27,
from /home/myfastcomp/emscripten/emscripten/system/include/emscripten.h:1,
from /home/CLionProjects/projectShell/library.h:8,
from /home/CLionProjects/projectShell/library.cpp:5:
/home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_config_minimal.h:3 7:22: error: conflicting declaration ‘typedef unsigned int size_t’
typedef unsigned int size_t;
^~~~~~
In file included from /usr/include/stdio.h:33:0,
from /home/myfastcomp/emscripten/emscripten/system/include/emscripten/emscripten.h:24,
from /home/myfastcomp/emscripten/emscripten/system/include/emscripten.h:1,
from /home/CLionProjects/projectShell/library.h:8,
from /home/CLionProjects/projectShell/library.cpp:5:
/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h:216:23: note: previous declaration as ‘typedef long unsigned int size_t’
typedef __SIZE_TYPE__ size_t;
^~~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:156:0,
from /usr/include/stdlib.h:394,
from /usr/include/c++/7/cstdlib:75,
from /usr/include/c++/7/stdlib.h:36,
from /usr/lib/gcc/x86_64-linux-gnu/7/include/mm_malloc.h:27,
from /usr/lib/gcc/x86_64-linux-gnu/7/include/xmmintrin.h:34,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_cpuinfo.h:59,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL.h:78,
from /home/myfastcomp/emscripten/emscripten/system/include/emscripten/emscripten.h:27,
from /home/hottab/myfastcomp/emscripten/emscripten/system/include/emscripten.h:1,
from /home/CLionProjects/projectShell/library.h:8,
from /home/CLionProjects/projectShell/library.cpp:5:
/usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error: conflicting declaration ‘typedef __int64_t int64_t’
typedef __int64_t int64_t;
^~~~~~~
In file included from
/home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_config.h:45:0,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_stdinc.h:31,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL_main.h:25,
from /home/myfastcomp/emscripten/emscripten/system/include/SDL/SDL.h:72,
from /home/myfastcomp/emscripten/emscripten/
system/include/emscripten/emscripten.h:27,
from /home/myfastcomp/emscripten/emscripten/
system/include/emscripten.h:1,
from /home/CLionProjects/projectShell/library.h:8,
from /home/CLionProjects/projectShell/library.cpp:5:
/home/myfastcomp/emscripten/
emscripten/system/include/SDL/SDL_config_minimal.h:44:26:
note: previous declaration as ‘typedef long long int
int64_t’
typedef signed long long int64_t;
^~~~~~~
In file included from
/home/myfastcomp/emscripten/emscripten/
system/include/emscripten.h:1:0,
from /home/CLionProjects/projectShell/library.h:8,
from /home/CLionProjects/projectShell/library.cpp:5:
/home/myfastcomp/emscripten/emscripten/
system/include/emscripten/emscripten.h:135:194: error:
wrong number of arguments specified for ‘deprecated’
attribute
void emscripten_set_canvas_size(int width, int height)
__attribute__((deprecated("This variant does not allow
specifying the target canvas", "Use
emscripten_set_canvas_element_size() instead")));
^
/home/myfastcomp/emscripten/emscripten/
system/include/emscripten/emscripten.h:136:254: error:
wrong number of arguments specified for ‘deprecated’ attribute
void emscripten_get_canvas_size(int *width, int *height,
int *isFullscreen) __attribute__((deprecated("This
variant does not allow specifying the target canvas",
"Use emscripten_get_canvas_element_size() and
emscripten_get_fullscreen_status() instead")));
^
CMakeFiles/projectShell.dir/build.make:75: recipe for
target 'CMakeFiles/projectShell.dir/library.cpp.o'
failed
make[3]: ***
[CMakeFiles/projectShell.dir/library.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:72: recipe for target
'CMakeFiles/projectShell.dir/all' failed
make[2]: *** [CMakeFiles/projectShell.dir/all] Error 2
CMakeFiles/Makefile2:84: recipe for target
'CMakeFiles/projectShell.dir/rule' failed
make[1]: *** [CMakeFiles/projectShell.dir/rule] Error 2
Makefile:118: recipe for target 'projectShell' failed
make: *** [projectShell] Error 2
您可以通过创建工具链、设置正确的环境变量并设置编译选项来使用 emscripten 进行编译。
在 Build, Execution, Deployment > Toolchains 中,添加一个新的系统工具链并将其命名为 Emscripten,并使用以下选项:
然后在 Build, Execution, Deployment > CMake 中,添加一个新的配置文件,例如 Debug-Emscripten。选择 Emscripten 工具链。您需要设置 CMake 选项和
emcmake
添加的环境变量。您可以通过设置环境变量EM_BUILD_VERBOSE=3
来查看选项,但是,要查看需要在emscripten的源代码中挖掘的环境(/usr/lib/emscripten/tools/shared.py
在我的机器上的函数get_building_env
中)。
要添加的 CMake 选项有:
-DCMAKE_CROSSCOMPILING_EMULATOR=path/to/node
-DCMAKE_TOOLCHAIN_FILE=path/to/cmake/Modules/Platform/Emscripten.cmake
我必须在我的机器上添加的环境变量是:
CC=path/to/emscripten/emcc
CXX=path/to/emscripten/em++
AR=path/to/emscripten/emar
LD=path/to/emscripten/emcc
NM=path/to/emscripten-llvm/llvm-nm
LDSHARED=path/to/emscripten/emcc
RANLIB=path/to/emscripten/emranlib
EMMAKEN_COMPILER=path/to/emscripten-llvm/clang++
EMSCRIPTEN_TOOLS=path/to/emscripten/tools
HOST_CC=path/to/emscripten-llvm/clang
HOST_CXX=path/to/emscripten-llvm/clang++
HOST_CFLAGS=-W
HOST_CXXFLAGS=-W
PKG_CONFIG_LIBDIR=path/to/emscripten/system/local/lib/pkgconfig:path/to/emscripten/system/lib/pkgconfig
PKG_CONFIG_PATH=
EMSCRIPTEN=path/to/emscripten
CROSS_COMPILE=path/to/emscripten/em
您现在应该能够通过选择 Debug-Emscripten 配置进行编译。
我在首选项->构建->cmake中设置了 emscripten 的工具链
-DCMAKE_TOOLCHAIN_FILE=..../sdks/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
在项目 cmake 中,我将源链接到可执行文件。对于编译标志,我使用参数。
set(CMAKE_EXECUTABLE_SUFFIX ".js")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_EXIT_RUNTIME=1 -s
EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']")
在这篇优秀的博客文章的帮助下,我能够创建一个 docker 镜像来使用 emscripten 工具链进行构建。
创建以下内容
Dockerfile
:
FROM emscripten/emsdk:latest
RUN DEBIAN_FRONTEND="noninteractive" apt-get update \
&& apt-get install -y ninja-build rsync ssh \
&& apt-get clean
RUN ( \
echo 'LogLevel DEBUG2'; \
echo 'PermitRootLogin yes'; \
echo 'PasswordAuthentication yes'; \
echo 'Subsystem sftp /usr/lib/openssh/sftp-server'; \
) > /etc/ssh/sshd_config_test_clion \
&& mkdir /run/sshd
# We need at least CMake 3.21 to support CMAKE_TOOLCHAIN_FILE from environment
RUN wget --no-verbose https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-x86_64.tar.gz --directory-prefix=/tmp \
&& tar xf /tmp/cmake-3.22.5-linux-x86_64.tar.gz -C /opt --strip-components=1 \
&& rm /tmp/cmake-3.22.5-linux-x86_64.tar.gz \
&& echo 'PATH=/opt/bin:$PATH' >> /etc/bash.bashrc
RUN mkdir /clion && ( \
echo 'export CMAKE_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake'; \
echo 'export CMAKE_GENERATOR=Ninja'; \
echo 'export CMAKE_C_COMPILER=$(which emcc)'; \
echo 'export CMAKE_CXX_COMPILER=$(which em++)'; \
echo 'export CC=$(which emcc)'; \
echo 'export CXX=$(which em++)'; \
) > /clion/emsdk.sh \
&& chmod a+x /clion/emsdk.sh
RUN useradd -m user \
&& yes password | passwd user
RUN usermod -s /bin/bash user
CMD ["/usr/sbin/sshd", "-D", "-e", "-f", "/etc/ssh/sshd_config_test_clion"]
使用以下命令构建图像:
docker build -f Dockerfile -t clion/emscripten .
启动一个新容器:
docker run -d --cap-add sys_ptrace -p127.0.0.1:2222:22 --name clion_emscripten clion/emscripten
emscripten 容器监听 ssh 端口 2222。 确切的值并不重要,但它必须是唯一的。
使用 CTRL+SHIFT+A ->“工具链”
打开“工具链设置”对话框添加新的“远程主机”工具链
远程主机位于 localhost:2222,用户名是“user”,密码是“password(不带双引号)。
使用
/clion/emsdk.sh
作为环境文件
使用
/opt/bin/cmake
作为 CMake 可执行文件
保留 C 编译器、C++ 编译器和调试器,然后按 OK
此后,您可以像使用本机工具链一样使用 Emscripten 工具链:
打开 CMake 设置对话框:SHIFT+A ->“cmake 设置”
使用 emscripten 工具链添加新的配置文件。
根据需要修改个人资料。 理想情况下,您可以保留默认值,只需要更改“构建类型”。
点击确定
现在您可以开始开发杀手级应用程序了。
CLion 不太理解“emcmake”和“emmake”命令的概念。目前最好的方法是从终端运行它。
理论上,应该可以不使用 emcmake 命令,并配置 CMake CLion 设置以使用特定于 emscripten 的工具链 cmake 文件,但由于某种原因,这不能很好地工作
我知道很久以前就有人问过这个问题,但是以下 cmake 预设对我来说适用于 clion:
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "debug",
"displayName": "Debug",
"generator": "Ninja",
"toolchainFile": "$env{EMSDK_ROOT}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CROSSCOMPILING_EMULATOR": "$env{EMSDK_ROOT}/node/14.18.2_64bit/bin/node.exe",
}
}
]
}
只需将环境变量
EMSDK_ROOT
设置为您的emsdk所在的位置即可。我可以从 clion 运行 ctests 等,但可惜我还没有弄清楚如何从 IDE 中调试它。