LLVM-C 创建目标文件导致:"TargetMachine can't emit a file of this type"
LLVM-C creating object file results in: "TargetMachine can't emit a file of this type"
尝试用 LLVM-C 生成一个非常简单的目标文件。不幸的是,我仍然坚持 "TargetMachine can't emit a file of this type" 尝试重新排序代码和 CPU 的各种东西(x64-64,通用和 LLVMGetHostCPUName())。显然这里缺少一些东西(希望很明显)。
下面的代码是用clang -Wall -O2 test.c LLVM-C.dll -o test
编译的
输出:
target: x86-64, [64-bit X86: EM64T and AMD64], 1, 1
triple: x86_64-pc-windows-msvc
features: +sse2,+cx16,+sahf,-tbm,-avx512ifma,+sha,-gfni,-fma4,-vpclmulqdq,+prfchw,+bmi2,-cldemote,+fsgsbase,-ptwrite,+xsavec,+popcnt,+aes,-avx512bitalg,-movdiri,+xsaves,-avx512er,-avx512vnni,-avx512vpopcntdq,-pconfig,-clwb,-avx512f,+clzero,-pku,+mmx,-lwp,-rdpid,-xop,+rdseed,-waitpkg,-movdir64b,+sse4a,-avx512bw,+clflushopt,+xsave,-avx512vbmi2,+64bit,-avx512vl,-invpcid,-avx512cd,+avx,-vaes,+cx8,+fma,-rtm,+bmi,-enqcmd,+rdrnd,+mwaitx,+sse4.1,+sse4.2,+avx2,+fxsr,-wbnoinvd,+sse,+lzcnt,+pclmul,-prefetchwt1,+f16c,+ssse3,-sgx,-shstk,+cmov,-avx512vbmi,-avx512bf16,+movbe,+xsaveopt,-avx512dq,+adx,-avx512pf,+sse3
datalayout: e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128
error: (null)
error: TargetMachine can't emit a file of this type
Module.txt:
; ModuleID = 'test'
source_filename = "test"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
define float @ftest() {
ftest:
ret float 0x401B333340000000
}
代码(test.c):
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/TargetMachine.h>
#include <stdio.h>
int main(){
LLVMInitializeNativeTarget();
LLVMTargetRef target = LLVMGetFirstTarget();
printf("target: %s, [%s], %d, %d\n", LLVMGetTargetName(target), LLVMGetTargetDescription(target), LLVMTargetHasJIT(target), LLVMTargetHasTargetMachine(target));
printf("triple: %s\n", LLVMGetDefaultTargetTriple());
printf("features: %s\n", LLVMGetHostCPUFeatures());
LLVMTargetMachineRef machine = LLVMCreateTargetMachine(target, LLVMGetDefaultTargetTriple(), "generic", LLVMGetHostCPUFeatures(), LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("test", context);
LLVMSetTarget(module, LLVMGetDefaultTargetTriple());
LLVMTargetDataRef datalayout = LLVMCreateTargetDataLayout(machine);
char* datalayout_str = LLVMCopyStringRepOfTargetData(datalayout);
printf("datalayout: %s\n", datalayout_str);
LLVMSetDataLayout(module, datalayout_str);
LLVMDisposeMessage(datalayout_str);
LLVMTypeRef f32 = LLVMFloatTypeInContext(context);
LLVMTypeRef ftype = LLVMFunctionType(f32, 0, 0, 0);
LLVMValueRef ftest = LLVMAddFunction(module, "ftest", ftype);
LLVMBasicBlockRef bb = LLVMAppendBasicBlockInContext(context, ftest, "ftest");
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMPositionBuilderAtEnd(builder, bb);
LLVMValueRef v1 = LLVMConstReal(f32, 2.5);
LLVMValueRef v2 = LLVMConstReal(f32, 4.3);
LLVMValueRef result = LLVMBuildFAdd(builder, v1, v2, "f-add");
LLVMBuildRet(builder, result);
LLVMVerifyFunction(ftest, LLVMPrintMessageAction);
char* errors = 0;
LLVMPrintModuleToFile(module, "module.txt", &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
LLVMTargetMachineEmitToFile(machine, module, "result.o", LLVMObjectFile, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
return 0;
}
好吧,经过更多的挖掘,我解决了这个问题。工作代码如下:
#include <llvm-c/Core.h>
#include <llvm-c/Transforms/PassManagerBuilder.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/TargetMachine.h>
#include <llvm-c/BitWriter.h>
#include <stdio.h>
int main(){
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("test", context);
LLVMTypeRef f32 = LLVMFloatTypeInContext(context);
LLVMTypeRef ftype = LLVMFunctionType(f32, 0, 0, 0);
LLVMValueRef ftest = LLVMAddFunction(module, "ftest", ftype);
LLVMBasicBlockRef bb = LLVMAppendBasicBlockInContext(context, ftest, "ftest");
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMPositionBuilderAtEnd(builder, bb);
LLVMValueRef v1 = LLVMConstReal(f32, 2.5);
LLVMValueRef v2 = LLVMConstReal(f32, 4.3);
LLVMValueRef result = LLVMBuildFAdd(builder, v1, v2, "f-add");
LLVMBuildRet(builder, result);
LLVMVerifyFunction(ftest, LLVMPrintMessageAction);
char* errors = 0;
LLVMPrintModuleToFile(module, "module.txt", &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllAsmParsers();
LLVMInitializeAllAsmPrinters();
LLVMTargetRef target;
LLVMGetTargetFromTriple(LLVMGetDefaultTargetTriple(), &target, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
printf("target: %s, [%s], %d, %d\n", LLVMGetTargetName(target), LLVMGetTargetDescription(target), LLVMTargetHasJIT(target), LLVMTargetHasTargetMachine(target));
printf("triple: %s\n", LLVMGetDefaultTargetTriple());
printf("features: %s\n", LLVMGetHostCPUFeatures());
LLVMTargetMachineRef machine = LLVMCreateTargetMachine(target, LLVMGetDefaultTargetTriple(), "generic", LLVMGetHostCPUFeatures(), LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
LLVMSetTarget(module, LLVMGetDefaultTargetTriple());
LLVMTargetDataRef datalayout = LLVMCreateTargetDataLayout(machine);
char* datalayout_str = LLVMCopyStringRepOfTargetData(datalayout);
printf("datalayout: %s\n", datalayout_str);
LLVMSetDataLayout(module, datalayout_str);
LLVMDisposeMessage(datalayout_str);
LLVMTargetMachineEmitToFile(machine, module, "result.o", LLVMObjectFile, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
return 0;
}
尝试用 LLVM-C 生成一个非常简单的目标文件。不幸的是,我仍然坚持 "TargetMachine can't emit a file of this type" 尝试重新排序代码和 CPU 的各种东西(x64-64,通用和 LLVMGetHostCPUName())。显然这里缺少一些东西(希望很明显)。
下面的代码是用clang -Wall -O2 test.c LLVM-C.dll -o test
输出:
target: x86-64, [64-bit X86: EM64T and AMD64], 1, 1
triple: x86_64-pc-windows-msvc
features: +sse2,+cx16,+sahf,-tbm,-avx512ifma,+sha,-gfni,-fma4,-vpclmulqdq,+prfchw,+bmi2,-cldemote,+fsgsbase,-ptwrite,+xsavec,+popcnt,+aes,-avx512bitalg,-movdiri,+xsaves,-avx512er,-avx512vnni,-avx512vpopcntdq,-pconfig,-clwb,-avx512f,+clzero,-pku,+mmx,-lwp,-rdpid,-xop,+rdseed,-waitpkg,-movdir64b,+sse4a,-avx512bw,+clflushopt,+xsave,-avx512vbmi2,+64bit,-avx512vl,-invpcid,-avx512cd,+avx,-vaes,+cx8,+fma,-rtm,+bmi,-enqcmd,+rdrnd,+mwaitx,+sse4.1,+sse4.2,+avx2,+fxsr,-wbnoinvd,+sse,+lzcnt,+pclmul,-prefetchwt1,+f16c,+ssse3,-sgx,-shstk,+cmov,-avx512vbmi,-avx512bf16,+movbe,+xsaveopt,-avx512dq,+adx,-avx512pf,+sse3
datalayout: e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128
error: (null)
error: TargetMachine can't emit a file of this type
Module.txt:
; ModuleID = 'test'
source_filename = "test"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
define float @ftest() {
ftest:
ret float 0x401B333340000000
}
代码(test.c):
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/TargetMachine.h>
#include <stdio.h>
int main(){
LLVMInitializeNativeTarget();
LLVMTargetRef target = LLVMGetFirstTarget();
printf("target: %s, [%s], %d, %d\n", LLVMGetTargetName(target), LLVMGetTargetDescription(target), LLVMTargetHasJIT(target), LLVMTargetHasTargetMachine(target));
printf("triple: %s\n", LLVMGetDefaultTargetTriple());
printf("features: %s\n", LLVMGetHostCPUFeatures());
LLVMTargetMachineRef machine = LLVMCreateTargetMachine(target, LLVMGetDefaultTargetTriple(), "generic", LLVMGetHostCPUFeatures(), LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("test", context);
LLVMSetTarget(module, LLVMGetDefaultTargetTriple());
LLVMTargetDataRef datalayout = LLVMCreateTargetDataLayout(machine);
char* datalayout_str = LLVMCopyStringRepOfTargetData(datalayout);
printf("datalayout: %s\n", datalayout_str);
LLVMSetDataLayout(module, datalayout_str);
LLVMDisposeMessage(datalayout_str);
LLVMTypeRef f32 = LLVMFloatTypeInContext(context);
LLVMTypeRef ftype = LLVMFunctionType(f32, 0, 0, 0);
LLVMValueRef ftest = LLVMAddFunction(module, "ftest", ftype);
LLVMBasicBlockRef bb = LLVMAppendBasicBlockInContext(context, ftest, "ftest");
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMPositionBuilderAtEnd(builder, bb);
LLVMValueRef v1 = LLVMConstReal(f32, 2.5);
LLVMValueRef v2 = LLVMConstReal(f32, 4.3);
LLVMValueRef result = LLVMBuildFAdd(builder, v1, v2, "f-add");
LLVMBuildRet(builder, result);
LLVMVerifyFunction(ftest, LLVMPrintMessageAction);
char* errors = 0;
LLVMPrintModuleToFile(module, "module.txt", &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
LLVMTargetMachineEmitToFile(machine, module, "result.o", LLVMObjectFile, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
return 0;
}
好吧,经过更多的挖掘,我解决了这个问题。工作代码如下:
#include <llvm-c/Core.h>
#include <llvm-c/Transforms/PassManagerBuilder.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/TargetMachine.h>
#include <llvm-c/BitWriter.h>
#include <stdio.h>
int main(){
LLVMContextRef context = LLVMContextCreate();
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("test", context);
LLVMTypeRef f32 = LLVMFloatTypeInContext(context);
LLVMTypeRef ftype = LLVMFunctionType(f32, 0, 0, 0);
LLVMValueRef ftest = LLVMAddFunction(module, "ftest", ftype);
LLVMBasicBlockRef bb = LLVMAppendBasicBlockInContext(context, ftest, "ftest");
LLVMBuilderRef builder = LLVMCreateBuilderInContext(context);
LLVMPositionBuilderAtEnd(builder, bb);
LLVMValueRef v1 = LLVMConstReal(f32, 2.5);
LLVMValueRef v2 = LLVMConstReal(f32, 4.3);
LLVMValueRef result = LLVMBuildFAdd(builder, v1, v2, "f-add");
LLVMBuildRet(builder, result);
LLVMVerifyFunction(ftest, LLVMPrintMessageAction);
char* errors = 0;
LLVMPrintModuleToFile(module, "module.txt", &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllAsmParsers();
LLVMInitializeAllAsmPrinters();
LLVMTargetRef target;
LLVMGetTargetFromTriple(LLVMGetDefaultTargetTriple(), &target, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
printf("target: %s, [%s], %d, %d\n", LLVMGetTargetName(target), LLVMGetTargetDescription(target), LLVMTargetHasJIT(target), LLVMTargetHasTargetMachine(target));
printf("triple: %s\n", LLVMGetDefaultTargetTriple());
printf("features: %s\n", LLVMGetHostCPUFeatures());
LLVMTargetMachineRef machine = LLVMCreateTargetMachine(target, LLVMGetDefaultTargetTriple(), "generic", LLVMGetHostCPUFeatures(), LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
LLVMSetTarget(module, LLVMGetDefaultTargetTriple());
LLVMTargetDataRef datalayout = LLVMCreateTargetDataLayout(machine);
char* datalayout_str = LLVMCopyStringRepOfTargetData(datalayout);
printf("datalayout: %s\n", datalayout_str);
LLVMSetDataLayout(module, datalayout_str);
LLVMDisposeMessage(datalayout_str);
LLVMTargetMachineEmitToFile(machine, module, "result.o", LLVMObjectFile, &errors);
printf("error: %s\n", errors);
LLVMDisposeMessage(errors);
return 0;
}