Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile time errors when including header file emscripten.h from $ENV{EMSDK}/upstream/emscripten/cache/sysroot/include/emscripten #22948

Open
reiend opened this issue Nov 18, 2024 · 11 comments

Comments

@reiend
Copy link

reiend commented Nov 18, 2024

emcc - v3.1.71

including header file emscripten.h compiles successfully but it causes compile time error
which hinders code completion such as emscripten_set_main_loop.

cmake config

target_include_directories(
	${CMAKE_PROJECT_NAME} 
	PUBLIC 
        $ENV{EMSDK}/upstream/emscripten/cache/sysroot/include/emscripten
)

for some unknown reason cmake can't include this specific path

$ENV{EMSDK}/upstream/emscripten/cache/sysroot/include

so i use

$ENV{EMSDK}/upstream/emscripten/cache/sysroot/include/emscripten

instead.

first error

In included file: 'emscripten/em_macros.h' file not found.
solution

// em_js.h
#include em_macros.h 

second new error

In included file: typedef redefinition with different types ('struct _iobuf' vs 'struct _IO_FILE') [redefinition_different_typedef].

// emscripten.h
struct _IO_FILE;
typedef struct _IO_FILE FILE;

char *emscripten_get_preloaded_image_data(const char *path, int *w, int *h);
char *emscripten_get_preloaded_image_data_from_FILE(FILE *file, int *w, int *h);

my naive solution

// emscripten.h
struct _IO_FILE;

char *emscripten_get_preloaded_image_data(const char *path, int *w, int *h);
char *emscripten_get_preloaded_image_data_from_FILE(_IO_FILE *file, int *w, int *h);

after the following changes compile time error gone and code completion now works.

@sbc100
Copy link
Collaborator

sbc100 commented Nov 18, 2024

Can you share the full compiler output? I imagine you could be mixing system headers with emscripten headers, but the full output should make it clean what the problem is.

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Can you share the full compiler output? I imagine you could be mixing system headers with emscripten headers, but the full output should make it clean what the problem is.

successfully compiles but compiler shows nothing
image

image

compiling with build tool cmake was a success too with compiler set to em++ --target=wasm32

the problem is the lsp I'm using, clangd can't seem to find where the headers are even though I included it in the target include directories and compile command json was on.

for some unknown reason cmake can't add this specifically in compile command json

$ENV{EMSDK}/upstream/emscripten/cache/sysroot/include
// this works
$ENV{EMSDK}/upstream/emscripten/cache/sysroot/include/emscripten

when I use clang++ --target=x86_64-windows-gnu, cmake outputs compile command json with the included headers successfully, this is where I encounter the compile time errors. unless I conditionally add headers

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
// do emscripten stuff
#endif

and remove

  $ENV{EMSDK}/upstream/emscripten/cache/sysroot/include

in cmake target include directories, program will not compile and will lose all the code completion lsp provided for emscripten.

@sbc100
Copy link
Collaborator

sbc100 commented Nov 18, 2024

Which LSP are you using?

The primary include path for emscripten should be upstream/emscripten/cache/sysroot/include. However you should not need to add this explicitly. Also, you can't use the emscripten headers with --target=x86_64-windows-gnu. That target should be wasm32-unknown-emscripten.

Can you not just tell the LSP to use emcc/em++ instead of raw clang/clang++. That would seem like the most (perhaps only) correct solution.

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Which LSP are you using?

The primary include path for emscripten should be upstream/emscripten/cache/sysroot/include. However you should not need to add this explicitly. Also, you can't use the emscripten headers with --target=x86_64-windows-gnu. That target should be wasm32-unknown-emscripten.

Can you not just tell the LSP to use emcc/em++ instead of raw clang/clang++. That would seem like the most (perhaps only) correct solution.

Thanks @sbc100 for quick response.

I use clangd.

changing target to wasm32-unknown-emscripten with clang++ as compiler gives me error

error: unable to create target: 'No available targets are compatible with triple "wasm32-unknown-emscripten"'

this error occur because by default this config

  set(CMAKE_C_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_C_COMPILER clang)
  set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_CXX_COMPILER clang++)

uses clang++ not provided by emscripten

// clang++ --print-targets
  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64

changing the config to use the emscripten provided clang++

  // $ENV{EMSDK}/upstream/bin/clang++.exe --print-targets
    Registered Targets:
    wasm32 - WebAssembly 32-bit
    wasm64 - WebAssembly 64-bit
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64
  
  set(CMAKE_C_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_C_COMPILER "$ENV{EMSDK}/upstream/bin/clang.exe")
  set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_CXX_COMPILER "$ENV{EMSDK}/upstream/bin/clang++.exe")

this gives me next error

FAILED: cmTC_dca1b.exe

    wasm-ld: error: unknown argument: --out-implib
    wasm-ld: error: unknown argument: --major-image-version
    wasm-ld: error: unknown argument: --minor-image-version
    wasm-ld: error: cannot open crt1.o: no such file or directory
    wasm-ld: error: cannot open libcmTC_aacba.dll.a: no such file or directory
    wasm-ld: error: cannot open 0: no such file or directory
    wasm-ld: error: cannot open 0: no such file or directory
    wasm-ld: error: unable to find library -lkernel32
    wasm-ld: error: unable to find library -luser32
    wasm-ld: error: unable to find library -lgdi32
    wasm-ld: error: unable to find library -lwinspool
    wasm-ld: error: unable to find library -lshell32
    wasm-ld: error: unable to find library -lole32
    wasm-ld: error: unable to find library -loleaut32
    wasm-ld: error: unable to find library -luuid
    wasm-ld: error: unable to find library -lcomdlg32
    wasm-ld: error: unable to find library -ladvapi32
    wasm-ld: error: unable to find library -lc++
    wasm-ld: error: unable to find library -lc++abi
    wasm-ld: error: unable to find library -lc

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Which LSP are you using?
The primary include path for emscripten should be upstream/emscripten/cache/sysroot/include. However you should not need to add this explicitly. Also, you can't use the emscripten headers with --target=x86_64-windows-gnu. That target should be wasm32-unknown-emscripten.
Can you not just tell the LSP to use emcc/em++ instead of raw clang/clang++. That would seem like the most (perhaps only) correct solution.

Thanks @sbc100 for quick response.

I use clangd.

changing target to wasm32-unknown-emscripten with clang++ as compiler gives me error

error: unable to create target: 'No available targets are compatible with triple "wasm32-unknown-emscripten"'

this error occur because by default this config

  set(CMAKE_C_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_C_COMPILER clang)
  set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_CXX_COMPILER clang++)

uses clang++ not provided by emscripten

// clang++ --print-targets
  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64

changing the config to use the emscripten provided clang++

  // $ENV{EMSDK}/upstream/bin/clang++.exe --print-targets
    Registered Targets:
    wasm32 - WebAssembly 32-bit
    wasm64 - WebAssembly 64-bit
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64
  
  set(CMAKE_C_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_C_COMPILER "$ENV{EMSDK}/upstream/bin/clang.exe")
  set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_CXX_COMPILER "$ENV{EMSDK}/upstream/bin/clang++.exe")

this gives me next error

FAILED: cmTC_dca1b.exe

    wasm-ld: error: unknown argument: --out-implib
    wasm-ld: error: unknown argument: --major-image-version
    wasm-ld: error: unknown argument: --minor-image-version
    wasm-ld: error: cannot open crt1.o: no such file or directory
    wasm-ld: error: cannot open libcmTC_aacba.dll.a: no such file or directory
    wasm-ld: error: cannot open 0: no such file or directory
    wasm-ld: error: cannot open 0: no such file or directory
    wasm-ld: error: unable to find library -lkernel32
    wasm-ld: error: unable to find library -luser32
    wasm-ld: error: unable to find library -lgdi32
    wasm-ld: error: unable to find library -lwinspool
    wasm-ld: error: unable to find library -lshell32
    wasm-ld: error: unable to find library -lole32
    wasm-ld: error: unable to find library -loleaut32
    wasm-ld: error: unable to find library -luuid
    wasm-ld: error: unable to find library -lcomdlg32
    wasm-ld: error: unable to find library -ladvapi32
    wasm-ld: error: unable to find library -lc++
    wasm-ld: error: unable to find library -lc++abi
    wasm-ld: error: unable to find library -lc

if it matters
OS - Windows NT
Terminal - Windows Terminal
Shell - Powershell

@sbc100
Copy link
Collaborator

sbc100 commented Nov 18, 2024

If you want to use em++/emcc with cmake the easiest way is to use emcmake (or -DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Platform/Emscripten.cmake)

The issues you are running into here are because cmake still thinks you are targetting windows, when you are not.

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Thank you for the suggestion @sbc100, I'll probably stick with the toolchain setup

  set(CMAKE_TOOLCHAIN_FILE $ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)
  set(CMAKE_C_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_C_COMPILER emcc)
  set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-emscripten) 
  set(CMAKE_CXX_COMPILER em++)

@sbc100
Copy link
Collaborator

sbc100 commented Nov 18, 2024

Thank you for the suggestion @sbc100, I'll probably stick with the toolchain setup

  set(CMAKE_TOOLCHAIN_FILE $ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)

If you use this line then you should not also need CMAKE_C_COMPILER_TARGET/CMAKE_C_COMPILER/etc since the Emscripten.cmake should take care of that.

@sbc100
Copy link
Collaborator

sbc100 commented Nov 18, 2024

Assuming that works can we close this issue?

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Thank you for the suggestion @sbc100, I'll probably stick with the toolchain setup

  set(CMAKE_TOOLCHAIN_FILE $ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)

If you use this line then you should not also need CMAKE_C_COMPILER_TARGET/CMAKE_C_COMPILER/etc since the Emscripten.cmake should take care of that.

noted.

@reiend
Copy link
Author

reiend commented Nov 18, 2024

Assuming that works can we close this issue?

this works and compiles successfully but still show lsp diagnostics errors cause of not including target directories for emscripten

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants