4

My question is regarding using a CMakeLists.txt with Emscriptem and specifying the output type along with a command line option.

I want to take a simple Emscripten command such as: emcc file.cpp -o file.html --preload-file asset_dir/ and change it to something that I can specify within my CMake system. I tried the naive approach of renaming the executable to have an extension of html but that didn't work. I also tried using -D--preload-file:PATH=asset_dir and that did not work either.

My CMakeLists.txt file is small and is contained below. I use the command emcmake cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=em++ .. && emmake make to build it.

CMAKE_MINIMUM_REQUIRED(VERSION 3.2.0 FATAL_ERROR)
PROJECT(ProjJS)

# Set typical CMAKE settings
SET(CMAKE_BUILD_TYPE_INIT "Release")
SET(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Turn on Verbose Makefiles" FORCE)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")

SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)

SET(PROJ_SOURCES
    hello.cpp
    ....
)

set(NAME_OF_EXE "ProjJS")

set(BOOST_LIB "boost")
set(BOOST_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extlibs/")
set(BOOST_LIB_PATH "${CMAKE_SOURCE_DIR}/extlibs/boost/libs/")

add_subdirectory(extlibs/boost)


SET(BOOST_PROGRAM_OPTIONS_SOURCES
    ${BOOST_LIB_PATH}/program_options/cmdline.cpp
    ${BOOST_LIB_PATH}/program_options/config_file.cpp
    ....
)

SET(BOOST_SYSTEM_SOURCES
    ${BOOST_LIB_PATH}/system/error_code.cpp
)

ADD_EXECUTABLE(${NAME_OF_EXE} ${PROJ_SOURCES})
add_library(${BOOST_LIB} STATIC ${BOOST_PROGRAM_OPTIONS_SOURCES} ${BOOST_SYSTEM_SOURCES})
TARGET_INCLUDE_DIRECTORIES(${BOOST_LIB} PUBLIC "${BOOST_INCLUDE_PATH}")

TARGET_LINK_LIBRARIES(${NAME_OF_EXE} PUBLIC ${BOOST_LIB})
TARGET_INCLUDE_DIRECTORIES(${NAME_OF_EXE} BEFORE PRIVATE "${CMAKE_SOURCE_DIR}/include")
TARGET_INCLUDE_DIRECTORIES(${NAME_OF_EXE} BEFORE PRIVATE "${BOOST_INCLUDE_PATH}" ${PROJ_SOURCES})
starball
  • 20,030
  • 7
  • 43
  • 238
BlazePascal
  • 391
  • 5
  • 12
  • I am not familiar with `emscripten`, but it seems that it differs a lot from "normal" compilers. So, it is not sufficient to just change a compiler executable, and expect CMake to do other work. Aside from the compiler itself you need to adjust many other compiler-related things. The best way for doing this is [toolchain file](https://cmake.org/cmake/help/v3.7/manual/cmake-toolchains.7.html). You may prepare your own toolchain file, or google for existed one. E.g., you may try [this toolchain](https://github.com/kripken/emscripten/blob/master/cmake/Modules/Platform/Emscripten.cmake). – Tsyvarev Feb 22 '17 at 07:39
  • Did you figure it out? Im stuck with the same (just made a ticket https://stackoverflow.com/questions/45260216/emscripten-cmake-pass-emscripten-options-in-cmakelist-file) – DutchKevv Jul 22 '17 at 23:42
  • I don't think you need to explicitly specify `CMAKE_CXX_COMPILER` when you're already wrapping with `emcmake`. `emcmake` adds the emscripten toolchain file argument, which should cover that for you. – starball Nov 27 '22 at 20:45

1 Answers1

3

For the output suffix this should work:

set(CMAKE_EXECUTABLE_SUFFIX ".html")

Complete example:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(demo)

set(CMAKE_EXECUTABLE_SUFFIX ".html")

add_executable(hello tests/hello_world.cpp)

That will emit hello.html etc.

For other flags, the best option I've found is to use target_link_libraries which CMake just appends to the link line, and can contain anything. For example:

target_link_libraries(binaryen_js "-s MODULARIZE")
target_link_libraries(binaryen_js "-s INITIAL_MEMORY=512MB")

That turns on modularize and sets the initial memory to 512MB (example from the Binaryen CMake script).

Alon Zakai
  • 31
  • 3
  • Why (ab)use `target_link_libraries` for linker flags when there is `target_link_options` dedicated for the purpose of setting linker flags? – starball Nov 27 '22 at 20:44
  • Good point, `target_link_options` is probably better. It was added later to CMake I think, so `target_link_libraries` was needed in the past but probably isn't today. – Alon Zakai Nov 28 '22 at 21:19