swift - 使用 `swiftc -emit-object` 构建目标文件也发出 `_main` 实现
问题描述
我目前正在使用swiftc
, 构建目标文件:
swiftc -emit-object bar.swift
bar.swift
像这样简单的东西在哪里:
class Bar {
var value: Int
init(value: Int) {
self.value = value
}
func plusValue(_ value: Int) -> Int {
return self.value + value
}
}
然后,当我继续将它与我的主要对象链接以创建可执行文件时,我收到以下错误:
$ cc -o foobar foo.o bar.o
duplicate symbol '_main' in:
foo.o
bar.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
这表明swiftc
正在向目标文件添加一个main
实现,可以通过以下方式确认:
$ nm bar.o | grep _main
0000000000000000 T _main
据我所知,这个添加的功能很少:
$ otool -tV bar.o
bar.o:
(__TEXT,__text) section
_main:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp, %rbp
0000000000000004 xorl %eax, %eax
0000000000000006 movl %edi, -0x4(%rbp)
0000000000000009 movq %rsi, -0x10(%rbp)
000000000000000d popq %rbp
000000000000000e retq
000000000000000f nop
....snip...
有没有办法告诉swiftc -emit-object
不要添加这个残留的实现main
?
解决方案
简短的回答
我缺少的命令行参数是:
-parse-as-library
长答案
在寻找答案的过程中,我求助于查看 Github 上的 Swift 源代码,幸运的是,在测试套件中发现了以下编译器调用:
// RUN: %target-build-swift %S/Inputs/CommandLineStressTest/CommandLineStressTest.swift -parse-as-library -force-single-frontend-invocation -module-name CommandLineStressTestSwift -emit-object -o %t/CommandLineStressTestSwift.o
根据swiftc --help
,-parse-as-library
导致编译器:
将输入文件解析为库,而不是脚本
事实证明这对我有用,导出符号的唯一区别是删除_main
:
$ diff -U1 <(swiftc -emit-object -module-name bar -o a.o bar.swift && nm a.o | cut -c18-) <(swiftc -emit-object -parse-as-library -module-name bar -o b.o bar.swift && nm b.o | cut -c18-)
--- /dev/fd/63 2020-03-28 17:13:08.000000000 +1100
+++ /dev/fd/62 2020-03-28 17:13:08.000000000 +1100
@@ -23,3 +23,2 @@
U __objc_empty_cache
-T _main
s _objc_classes
在生成的程序集中,唯一的变化是删除了_main
代码:
$ diff -U1 <(swiftc -emit-object -module-name bar -o a.o bar.swift && objdump -d -no-leading-addr -no-show-raw-insn a.o) <(swiftc -emit-object -parse-as-library -module-name bar -o b.o bar.swift && objdump -d -no-leading-addr -no-show-raw-insn b.o)
--- /dev/fd/63 2020-03-28 17:19:03.000000000 +1100
+++ /dev/fd/62 2020-03-28 17:19:03.000000000 +1100
@@ -1,15 +1,5 @@
-a.o: file format Mach-O 64-bit x86-64
+b.o: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
-_main:
- pushq %rbp
- movq %rsp, %rbp
- xorl %eax, %eax
- movl %edi, -4(%rbp)
- movq %rsi, -16(%rbp)
- popq %rbp
- retq
- nop
-
_$S3bar3BarC5valueSivg:
推荐阅读
- python - ImportError:无法导入名称“MyLibrary”
- api - 是否可以让 Bitly 保留编码的查询参数?
- python - 识别 SimpleImputer 删除的功能
- java - Java Robot截图效率
- php - PHP 扩展统计
- c++ - 链接器找不到 -lgcc [CMU Malloc 实验室]
- r - 为什么当我运行 ggttest 时出现错误?
- sql - SQL Server 2012 - 在 WHERE 子句下具有两个条件的递归 CTE
- python - 无法使用 Python 在 Selenium Webdriver 中单击框
- c# - NETSPARKER ENTERPRISE SCAN REPORT 对应用程序进行 XSS 攻击时如何处理内部服务器错误