Support external toolchain on Windows for aot compiler (#3911)
allowing custom ARC toolchain on Windows
This commit is contained in:
@ -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(
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user