gcc无法链接llc输出的objfile

gcc无法链接llc输出的objfile,gcc,llvm,Gcc,Llvm,我是LLVM的新手,尝试在wsl上的Ubuntu20.04上构建自己的编译器。我使用的是llvm-12,得到的llvm IR文件如下: ; ModuleID = 'main' source_filename = "main" @ic = constant i32 1 @rc = constant double 1.500000e+00 @bc = constant i1 false @cc = constant i8 97 @iv = global i32 0 @rv =

我是LLVM的新手,尝试在wsl上的Ubuntu20.04上构建自己的编译器。我使用的是llvm-12,得到的llvm IR文件如下:

; ModuleID = 'main'
source_filename = "main"

@ic = constant i32 1
@rc = constant double 1.500000e+00
@bc = constant i1 false
@cc = constant i8 97
@iv = global i32 0
@rv = global double 0.000000e+00
@bv = global i1 false
@cv = global i8 0
@.str = constant [4 x i8] c"%d\0A\00"
@.str.1 = constant [5 x i8] c"%lf\0A\00"
@.str.2 = constant [4 x i8] c"%d\0A\00"
@.str.3 = constant [4 x i8] c"%c\0A\00"
@.str.4 = constant [4 x i8] c"%d\0A\00"
@.str.5 = constant [5 x i8] c"%lf\0A\00"
@.str.6 = constant [4 x i8] c"%d\0A\00"
@.str.7 = constant [4 x i8] c"%c\0A\00"

define internal void @main() {
entrypoint:
  store i32 1, i32* @iv, align 4
  store double 9.990000e+01, double* @rv, align 8
  store i1 true, i1* @bv, align 1
  store i8 97, i8* @cv, align 1
  %tmp = load i32, i32* @ic, align 4
  %printf = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %tmp)
  %tmp1 = load double, double* @rc, align 8
  %printf2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i32 0, i32 0), double %tmp1)
  %tmp3 = load i1, i1* @bc, align 1
  %printf4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i1 %tmp3)
  %tmp5 = load i8, i8* @cc, align 1
  %printf6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0), i8 %tmp5)
  %tmp7 = load i32, i32* @iv, align 4
  %printf8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), i32 %tmp7)
  %tmp9 = load double, double* @rv, align 8
  %printf10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i32 0, i32 0), double %tmp9)
  %tmp11 = load i1, i1* @bv, align 1
  %printf12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i32 0, i32 0), i1 %tmp11)
  %tmp13 = load i8, i8* @cv, align 1
  %printf14 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0), i8 %tmp13)
  ret void
}

declare i32 @printf(i8*, ...)

declare i32 @scanf(...)
我可以使用lli来运行它,它运行得很好。但我想构建可执行二进制文件,所以我使用llc生成asm代码,并得到以下结果:

    .text
    .file   "main"
    .p2align    4, 0x90                         # -- Begin function main
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# %bb.0:                                # %entrypoint
    pushq   %r15
    .cfi_def_cfa_offset 16
    pushq   %r14
    .cfi_def_cfa_offset 24
    pushq   %r12
    .cfi_def_cfa_offset 32
    pushq   %rbx
    .cfi_def_cfa_offset 40
    pushq   %rax
    .cfi_def_cfa_offset 48
    .cfi_offset %rbx, -40
    .cfi_offset %r12, -32
    .cfi_offset %r14, -24
    .cfi_offset %r15, -16
    movq    iv@GOTPCREL(%rip), %rbx
    movl    $1, (%rbx)
    movq    rv@GOTPCREL(%rip), %r12
    movabsq $4636730254480218522, %rax      # imm = 0x4058F9999999999A
    movq    %rax, (%r12)
    movq    bv@GOTPCREL(%rip), %r15
    movb    $1, (%r15)
    movq    cv@GOTPCREL(%rip), %r14
    movb    $97, (%r14)
    movq    ic@GOTPCREL(%rip), %rax
    movl    (%rax), %esi
    movq    .str@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    movq    rc@GOTPCREL(%rip), %rax
    movsd   (%rax), %xmm0                   # xmm0 = mem[0],zero
    movq    .str.1@GOTPCREL(%rip), %rdi
    movb    $1, %al
    callq   printf@PLT
    movq    bc@GOTPCREL(%rip), %rax
    movzbl  (%rax), %esi
    movq    .str.2@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    movq    cc@GOTPCREL(%rip), %rax
    movzbl  (%rax), %esi
    movq    .str.3@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    movl    (%rbx), %esi
    movq    .str.4@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    movsd   (%r12), %xmm0                   # xmm0 = mem[0],zero
    movq    .str.5@GOTPCREL(%rip), %rdi
    movb    $1, %al
    callq   printf@PLT
    movzbl  (%r15), %esi
    movq    .str.6@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    movzbl  (%r14), %esi
    movq    .str.7@GOTPCREL(%rip), %rdi
    xorl    %eax, %eax
    callq   printf@PLT
    addq    $8, %rsp
    .cfi_def_cfa_offset 40
    popq    %rbx
    .cfi_def_cfa_offset 32
    popq    %r12
    .cfi_def_cfa_offset 24
    popq    %r14
    .cfi_def_cfa_offset 16
    popq    %r15
    .cfi_def_cfa_offset 8
    retq
.Lfunc_end0:
    .size   main, .Lfunc_end0-main
    .cfi_endproc
                                        # -- End function
    .type   ic,@object                      # @ic
    .section    .rodata,"a",@progbits
    .globl  ic
    .p2align    2
ic:
    .long   1                               # 0x1
    .size   ic, 4

    .type   rc,@object                      # @rc
    .globl  rc
    .p2align    3
rc:
    .quad   0x3ff8000000000000              # double 1.5
    .size   rc, 8

    .type   bc,@object                      # @bc
    .globl  bc
bc:
    .byte   0                               # 0x0
    .size   bc, 1

    .type   cc,@object                      # @cc
    .globl  cc
cc:
    .byte   97                              # 0x61
    .size   cc, 1

    .type   iv,@object                      # @iv
    .bss
    .globl  iv
    .p2align    2
iv:
    .long   0                               # 0x0
    .size   iv, 4

    .type   rv,@object                      # @rv
    .globl  rv
    .p2align    3
rv:
    .quad   0x0000000000000000              # double 0
    .size   rv, 8

    .type   bv,@object                      # @bv
    .globl  bv
bv:
    .byte   0                               # 0x0
    .size   bv, 1

    .type   cv,@object                      # @cv
    .globl  cv
cv:
    .byte   0                               # 0x0
    .size   cv, 1

    .type   .str,@object                    # @.str
    .section    .rodata,"a",@progbits
    .globl  .str
.str:
    .asciz  "%d\n"
    .size   .str, 4

    .type   .str.1,@object                  # @.str.1
    .globl  .str.1
.str.1:
    .asciz  "%lf\n"
    .size   .str.1, 5

    .type   .str.2,@object                  # @.str.2
    .globl  .str.2
.str.2:
    .asciz  "%d\n"
    .size   .str.2, 4

    .type   .str.3,@object                  # @.str.3
    .globl  .str.3
.str.3:
    .asciz  "%c\n"
    .size   .str.3, 4

    .type   .str.4,@object                  # @.str.4
    .globl  .str.4
.str.4:
    .asciz  "%d\n"
    .size   .str.4, 4

    .type   .str.5,@object                  # @.str.5
    .globl  .str.5
.str.5:
    .asciz  "%lf\n"
    .size   .str.5, 5

    .type   .str.6,@object                  # @.str.6
    .globl  .str.6
.str.6:
    .asciz  "%d\n"
    .size   .str.6, 4

    .type   .str.7,@object                  # @.str.7
    .globl  .str.7
.str.7:
    .asciz  "%c\n"
    .size   .str.7, 4

    .section    ".note.GNU-stack","",@progbits
正如您所看到的,没有“.global main”,因此当我运行gcc buildtest.s-o buildtest时,我得到:

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status

因此,我必须自己添加“.global main”。我怎样才能摆脱这个问题?

你好,Martin Lee,欢迎来到stack overflow。你可以尝试从主DEF中移除“内部”链接类型,定义Value@主(){看看它是否工作。谢谢,这是有效的。但是我怎样才能自动地删除LVVM?你运行什么命令来创建位码?我写C++代码(使用LLVM C++ API)为了构建一个输出LLVM IR的分析器,类似于,我想我在代码中忘记了一些东西,所以LLVM把主元素看作是一个内部函数。当你使用正确的链接类型时,就这样。我使用<代码>外部链接> /代码>。