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": [],
|
||||
}
|
||||
|
||||
experimental_backends = ["ARC", "Xtensa"]
|
||||
normal_backends = [s for s in backends if s not in experimental_backends]
|
||||
|
||||
LLVM_TARGETS_TO_BUILD = [
|
||||
'-DLLVM_TARGETS_TO_BUILD:STRING="' + ";".join(backends) + '"'
|
||||
if backends
|
||||
'-DLLVM_TARGETS_TO_BUILD:STRING="' + ";".join(normal_backends) + '"'
|
||||
if normal_backends
|
||||
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 = [
|
||||
'-DLLVM_ENABLE_PROJECTS:STRING="' + ";".join(projects) + '"' if projects else ""
|
||||
]
|
||||
@ -240,6 +255,7 @@ def main():
|
||||
"X86",
|
||||
"Xtensa",
|
||||
],
|
||||
default=[],
|
||||
help="identify LLVM supported backends, separate by space, like '--arch ARM Mips X86'",
|
||||
)
|
||||
parser.add_argument(
|
||||
|
||||
@ -4093,39 +4093,6 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
|
||||
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 *
|
||||
aot_generate_tempfile_name(const char *prefix, const char *extension,
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4148,7 +4116,6 @@ aot_generate_tempfile_name(const char *prefix, const char *extension,
|
||||
snprintf(buffer + name_len, len - name_len, ".%s", extension);
|
||||
return buffer;
|
||||
}
|
||||
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
|
||||
|
||||
bool
|
||||
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");
|
||||
|
||||
#if !(defined(_WIN32) || defined(_WIN32_))
|
||||
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
|
||||
char cmd[1024];
|
||||
int ret;
|
||||
@ -4270,7 +4236,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
||||
file_name, bc_file_name);
|
||||
LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd);
|
||||
|
||||
ret = system(cmd);
|
||||
ret = bh_system(cmd);
|
||||
/* remove temp bitcode file */
|
||||
unlink(bc_file_name);
|
||||
|
||||
@ -4323,7 +4289,7 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
||||
file_name, asm_file_name);
|
||||
LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd);
|
||||
|
||||
ret = system(cmd);
|
||||
ret = bh_system(cmd);
|
||||
/* remove temp assembly file */
|
||||
unlink(asm_file_name);
|
||||
|
||||
@ -4336,7 +4302,6 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
|
||||
|
||||
if (!strncmp(LLVMGetTargetName(target), "arc", 3))
|
||||
/* 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");
|
||||
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 */
|
||||
int ret;
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||
}
|
||||
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
|
||||
as it cannot emit to object file */
|
||||
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.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* close and remove temp file */
|
||||
close(fd);
|
||||
unlink(file_name);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
|
||||
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
|
||||
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 ",
|
||||
"-mcpu=arcem -o ", file_name, ".o -c ", file_name, ".s");
|
||||
/* TODO: use try..catch to handle possible exceptions */
|
||||
ret = system(buf);
|
||||
ret = bh_system(buf);
|
||||
/* remove temp assembly file */
|
||||
snprintf(buf, sizeof(buf), "%s%s", file_name, ".s");
|
||||
unlink(buf);
|
||||
@ -4391,7 +4378,6 @@ aot_obj_data_create(AOTCompContext *comp_ctx)
|
||||
aot_set_last_error("create mem buffer with file failed.");
|
||||
goto fail;
|
||||
}
|
||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||
}
|
||||
else {
|
||||
if (LLVMTargetMachineEmitToMemoryBuffer(
|
||||
|
||||
@ -2746,10 +2746,6 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
|
||||
/* verify external llc compiler */
|
||||
comp_ctx->external_llc_compiler = getenv("WAMRC_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) {
|
||||
LOG_WARNING("WAMRC_LLC_COMPILER [%s] not found, fallback to "
|
||||
"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]",
|
||||
comp_ctx->external_llc_compiler);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* verify external asm compiler */
|
||||
if (!comp_ctx->external_llc_compiler) {
|
||||
comp_ctx->external_asm_compiler = getenv("WAMRC_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) {
|
||||
LOG_WARNING(
|
||||
"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]",
|
||||
comp_ctx->external_asm_compiler);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,18 @@
|
||||
#include "aot_orc_extra.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
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -165,3 +165,53 @@ wa_strdup(const char *s)
|
||||
}
|
||||
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 *
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user