Support external toolchain on Windows for aot compiler (#3911)

allowing custom ARC toolchain on Windows
This commit is contained in:
TianlongLiang
2024-11-19 17:47:05 +08:00
committed by GitHub
parent 2975e2ffb8
commit f2b87d773e
7 changed files with 97 additions and 68 deletions

View File

@ -102,12 +102,27 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
"default": [], "default": [],
} }
experimental_backends = ["ARC", "Xtensa"]
normal_backends = [s for s in backends if s not in experimental_backends]
LLVM_TARGETS_TO_BUILD = [ LLVM_TARGETS_TO_BUILD = [
'-DLLVM_TARGETS_TO_BUILD:STRING="' + ";".join(backends) + '"' '-DLLVM_TARGETS_TO_BUILD:STRING="' + ";".join(normal_backends) + '"'
if backends if normal_backends
else '-DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;Mips;RISCV;X86"' else '-DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;Mips;RISCV;X86"'
] ]
# if not on ARC platform, but want to add expeirmental backend ARC as target
if platform != "ARC" and "ARC" in backends:
LLVM_TARGETS_TO_BUILD.extend(
LLVM_EXTRA_COMPILE_OPTIONS["arc"]
)
if platform != "Xtensa" and "Xtensa" in backends:
print(
"Currently it's not supported to build Xtensa backend on non-Xtensa platform"
)
return None
LLVM_PROJECTS_TO_BUILD = [ LLVM_PROJECTS_TO_BUILD = [
'-DLLVM_ENABLE_PROJECTS:STRING="' + ";".join(projects) + '"' if projects else "" '-DLLVM_ENABLE_PROJECTS:STRING="' + ";".join(projects) + '"' if projects else ""
] ]
@ -240,6 +255,7 @@ def main():
"X86", "X86",
"Xtensa", "Xtensa",
], ],
default=[],
help="identify LLVM supported backends, separate by space, like '--arch ARM Mips X86'", help="identify LLVM supported backends, separate by space, like '--arch ARM Mips X86'",
) )
parser.add_argument( parser.add_argument(

View File

@ -4093,39 +4093,6 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
return true; return true;
} }
#if !(defined(_WIN32) || defined(_WIN32_))
char *
aot_generate_tempfile_name(const char *prefix, const char *extension,
char *buffer, uint32 len)
{
int fd, name_len;
name_len = snprintf(buffer, len, "%s-XXXXXX", prefix);
if ((fd = mkstemp(buffer)) <= 0) {
aot_set_last_error("make temp file failed.");
return NULL;
}
/* close and remove temp file */
close(fd);
unlink(buffer);
/* Check if buffer length is enough */
/* name_len + '.' + extension + '\0' */
if (name_len + 1 + strlen(extension) + 1 > len) {
aot_set_last_error("temp file name too long.");
return NULL;
}
snprintf(buffer + name_len, len - name_len, ".%s", extension);
return buffer;
}
#else
errno_t
_mktemp_s(char *nameTemplate, size_t sizeInChars);
char * char *
aot_generate_tempfile_name(const char *prefix, const char *extension, aot_generate_tempfile_name(const char *prefix, const char *extension,
char *buffer, uint32 len) char *buffer, uint32 len)
@ -4134,7 +4101,8 @@ aot_generate_tempfile_name(const char *prefix, const char *extension,
name_len = snprintf(buffer, len, "%s-XXXXXX", prefix); name_len = snprintf(buffer, len, "%s-XXXXXX", prefix);
if (_mktemp_s(buffer, name_len + 1) != 0) { if (!bh_mkstemp(buffer, name_len + 1)) {
aot_set_last_error("make temp file failed.");
return NULL; return NULL;
} }
@ -4148,7 +4116,6 @@ aot_generate_tempfile_name(const char *prefix, const char *extension,
snprintf(buffer + name_len, len - name_len, ".%s", extension); snprintf(buffer + name_len, len - name_len, ".%s", extension);
return buffer; return buffer;
} }
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
bool bool
aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name) aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name)
@ -4227,7 +4194,6 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
bh_print_time("Begin to emit object file"); bh_print_time("Begin to emit object file");
#if !(defined(_WIN32) || defined(_WIN32_))
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) { if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
char cmd[1024]; char cmd[1024];
int ret; int ret;
@ -4270,7 +4236,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
file_name, bc_file_name); file_name, bc_file_name);
LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd); LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd);
ret = system(cmd); ret = bh_system(cmd);
/* remove temp bitcode file */ /* remove temp bitcode file */
unlink(bc_file_name); unlink(bc_file_name);
@ -4323,7 +4289,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
file_name, asm_file_name); file_name, asm_file_name);
LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd); LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd);
ret = system(cmd); ret = bh_system(cmd);
/* remove temp assembly file */ /* remove temp assembly file */
unlink(asm_file_name); unlink(asm_file_name);
@ -4336,7 +4302,6 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
return true; return true;
} }
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
if (!strncmp(LLVMGetTargetName(target), "arc", 3)) if (!strncmp(LLVMGetTargetName(target), "arc", 3))
/* Emit to assembly file instead for arc target /* Emit to assembly file instead for arc target

View File

@ -4292,10 +4292,6 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
bh_print_time("Begin to emit object file"); bh_print_time("Begin to emit object file");
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) { if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
#if defined(_WIN32) || defined(_WIN32_)
aot_set_last_error("external toolchain not supported on Windows");
goto fail;
#else
/* Generate a temp file name */ /* Generate a temp file name */
int ret; int ret;
char obj_file_name[64]; char obj_file_name[64];
@ -4323,27 +4319,18 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
aot_set_last_error("create mem buffer with file failed."); aot_set_last_error("create mem buffer with file failed.");
goto fail; goto fail;
} }
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
} }
else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) { else if (!strncmp(LLVMGetTargetName(target), "arc", 3)) {
#if defined(_WIN32) || defined(_WIN32_)
aot_set_last_error("emit object file on Windows is unsupported.");
goto fail;
#else
/* Emit to assembly file instead for arc target /* Emit to assembly file instead for arc target
as it cannot emit to object file */ as it cannot emit to object file */
char file_name[] = "wasm-XXXXXX", buf[128]; char file_name[] = "wasm-XXXXXX", buf[128];
int fd, ret; int ret;
if ((fd = mkstemp(file_name)) <= 0) { if (!bh_mkstemp(file_name, sizeof(file_name))) {
aot_set_last_error("make temp file failed."); aot_set_last_error("make temp file failed.");
goto fail; goto fail;
} }
/* close and remove temp file */
close(fd);
unlink(file_name);
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine, if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
comp_ctx->module, buf, LLVMAssemblyFile, comp_ctx->module, buf, LLVMAssemblyFile,
@ -4364,7 +4351,7 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
"/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ", "/opt/zephyr-sdk/arc-zephyr-elf/bin/arc-zephyr-elf-gcc ",
"-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s"); "-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s");
/* TODO: use try..catch to handle possible exceptions */ /* TODO: use try..catch to handle possible exceptions */
ret = system(buf); ret = bh_system(buf);
/* remove temp assembly file */ /* remove temp assembly file */
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s"); snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
unlink(buf); unlink(buf);
@ -4391,7 +4378,6 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
aot_set_last_error("create mem buffer with file failed."); aot_set_last_error("create mem buffer with file failed.");
goto fail; goto fail;
} }
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
} }
else { else {
if (LLVMTargetMachineEmitToMemoryBuffer( if (LLVMTargetMachineEmitToMemoryBuffer(

View File

@ -2746,10 +2746,6 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
/* verify external llc compiler */ /* verify external llc compiler */
comp_ctx->external_llc_compiler = getenv("WAMRC_LLC_COMPILER"); comp_ctx->external_llc_compiler = getenv("WAMRC_LLC_COMPILER");
if (comp_ctx->external_llc_compiler) { if (comp_ctx->external_llc_compiler) {
#if defined(_WIN32) || defined(_WIN32_)
comp_ctx->external_llc_compiler = NULL;
LOG_WARNING("External LLC compiler not supported on Windows.");
#else
if (access(comp_ctx->external_llc_compiler, X_OK) != 0) { if (access(comp_ctx->external_llc_compiler, X_OK) != 0) {
LOG_WARNING("WAMRC_LLC_COMPILER [%s] not found, fallback to " LOG_WARNING("WAMRC_LLC_COMPILER [%s] not found, fallback to "
"default pipeline", "default pipeline",
@ -2761,17 +2757,12 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
LOG_VERBOSE("Using external LLC compiler [%s]", LOG_VERBOSE("Using external LLC compiler [%s]",
comp_ctx->external_llc_compiler); comp_ctx->external_llc_compiler);
} }
#endif
} }
/* verify external asm compiler */ /* verify external asm compiler */
if (!comp_ctx->external_llc_compiler) { if (!comp_ctx->external_llc_compiler) {
comp_ctx->external_asm_compiler = getenv("WAMRC_ASM_COMPILER"); comp_ctx->external_asm_compiler = getenv("WAMRC_ASM_COMPILER");
if (comp_ctx->external_asm_compiler) { if (comp_ctx->external_asm_compiler) {
#if defined(_WIN32) || defined(_WIN32_)
comp_ctx->external_asm_compiler = NULL;
LOG_WARNING("External ASM compiler not supported on Windows.");
#else
if (access(comp_ctx->external_asm_compiler, X_OK) != 0) { if (access(comp_ctx->external_asm_compiler, X_OK) != 0) {
LOG_WARNING( LOG_WARNING(
"WAMRC_ASM_COMPILER [%s] not found, fallback to " "WAMRC_ASM_COMPILER [%s] not found, fallback to "
@ -2784,7 +2775,6 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
LOG_VERBOSE("Using external ASM compiler [%s]", LOG_VERBOSE("Using external ASM compiler [%s]",
comp_ctx->external_asm_compiler); comp_ctx->external_asm_compiler);
} }
#endif
} }
} }

View File

@ -37,6 +37,18 @@
#include "aot_orc_extra.h" #include "aot_orc_extra.h"
#include "aot_comp_option.h" #include "aot_comp_option.h"
#if defined(_WIN32) || defined(_WIN32_)
#include <io.h>
#define access _access
/* On windows there is no X_OK flag to check for executablity, only check for
* existence */
#ifdef X_OK
#undef X_OK
#endif
#define X_OK 00
#define unlink _unlink
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -165,3 +165,53 @@ wa_strdup(const char *s)
} }
return s1; return s1;
} }
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
int
bh_system(const char *cmd)
{
int ret;
#if !(defined(_WIN32) || defined(_WIN32_))
ret = system(cmd);
#else
ret = _spawnlp(_P_WAIT, "cmd.exe", "/c", cmd, NULL);
#endif
return ret;
}
#if defined(_WIN32) || defined(_WIN32_)
errno_t
_mktemp_s(char *nameTemplate, size_t sizeInChars);
#endif
bool
bh_mkstemp(char *file_name, size_t name_len)
{
int fd;
#if !(defined(_WIN32) || defined(_WIN32_))
(void)name_len;
/* On Linux, it generates a unique temporary filename from template, creates
* and opens the file, and returns an open file descriptor for the file. */
if ((fd = mkstemp(file_name)) <= 0) {
goto fail;
}
/* close and remove temp file */
close(fd);
unlink(file_name);
#else
/* On Windows, it generates a unique temporary file name but does not create
* or open the file */
if (_mktemp_s(file_name, name_len) != 0) {
goto fail;
}
#endif
return true;
fail:
return false;
}
#endif /* End of WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0 */

View File

@ -66,6 +66,16 @@ bh_strdup(const char *s);
char * char *
wa_strdup(const char *s); wa_strdup(const char *s);
#if WASM_ENABLE_WAMR_COMPILER != 0 || WASM_ENABLE_JIT != 0
/* Executes a system command in bash/cmd.exe */
int
bh_system(const char *cmd);
/* Tests whether can create a temporary file with the given name */
bool
bh_mkstemp(char *filename, size_t name_len);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif