Skip to content

Commit 387f894

Browse files
authored
[native_toolchain_c] Default handling for PIC/PIE compiler flags (#121)
1 parent 0a4e5f8 commit 387f894

11 files changed

+224
-107
lines changed

pkgs/native_toolchain_c/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.2.2
2+
3+
- Generate position independent code for libraries by default and add
4+
`pic` option to control this behavior.
5+
16
## 0.2.1
27

38
- Added `defines` for specifying custom defines.

pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ class CBuilder implements Builder {
8181
/// Defaults to `true`.
8282
final bool ndebugDefine;
8383

84+
/// Whether the compiler will emit position independent code.
85+
///
86+
/// When set to `true`, libraries will be compiled with `-fPIC` and
87+
/// executables with `-fPIE`. Accordingly the corresponding parameter of the
88+
/// [executable] constructor is named `pie`.
89+
///
90+
/// When set to `null`, the default behavior of the compiler will be used.
91+
///
92+
/// This option has no effect when building for Windows, where generation of
93+
/// position independent code is not configurable.
94+
///
95+
/// Defaults to `true` for libraries and `false` for executables.
96+
final bool? pic;
97+
8498
CBuilder.library({
8599
required this.name,
86100
required this.assetId,
@@ -90,6 +104,7 @@ class CBuilder implements Builder {
90104
this.defines = const {},
91105
this.buildModeDefine = true,
92106
this.ndebugDefine = true,
107+
this.pic = true,
93108
}) : _type = _CBuilderType.library;
94109

95110
CBuilder.executable({
@@ -99,9 +114,11 @@ class CBuilder implements Builder {
99114
this.defines = const {},
100115
this.buildModeDefine = true,
101116
this.ndebugDefine = true,
117+
bool? pie = false,
102118
}) : _type = _CBuilderType.executable,
103119
assetId = null,
104-
installName = null;
120+
installName = null,
121+
pic = pie;
105122

106123
/// Runs the C Compiler with on this C build spec.
107124
///
@@ -148,6 +165,7 @@ class CBuilder implements Builder {
148165
if (ndebugDefine && buildConfig.buildMode != BuildMode.debug)
149166
'NDEBUG': null,
150167
},
168+
pic: pic,
151169
);
152170
await task.run();
153171
}

pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ class RunCBuilder {
2525
final Uri outDir;
2626
final Target target;
2727

28-
/// The install of the [dynamicLibrary].
28+
/// The install name of the [dynamicLibrary].
2929
///
3030
/// Can be inspected with `otool -D <path-to-dylib>`.
3131
///
3232
/// Can be modified with `install_name_tool`.
3333
final Uri? installName;
3434

3535
final Map<String, String?> defines;
36+
final bool? pic;
3637

3738
RunCBuilder({
3839
required this.buildConfig,
@@ -43,6 +44,7 @@ class RunCBuilder {
4344
this.staticLibrary,
4445
this.installName,
4546
this.defines = const {},
47+
this.pic,
4648
}) : outDir = buildConfig.outDir,
4749
target = buildConfig.target,
4850
assert([executable, dynamicLibrary, staticLibrary]
@@ -145,6 +147,20 @@ class RunCBuilder {
145147
'-o',
146148
outDir.resolve('out.o').toFilePath(),
147149
],
150+
if (pic != null)
151+
if (pic!) ...[
152+
if (dynamicLibrary != null) '-fPIC',
153+
// Using PIC for static libraries allows them to be linked into
154+
// any executable, but it is not necessarily the best option in
155+
// terms of overhead. We would have to know wether the target into
156+
// which the static library is linked is PIC, PIE or neither. Then
157+
// we could use the same option for the static library.
158+
if (staticLibrary != null) '-fPIC',
159+
if (executable != null) '-fPIE',
160+
] else ...[
161+
'-fno-PIC',
162+
'-fno-PIE',
163+
],
148164
for (final MapEntry(key: name, :value) in defines.entries)
149165
if (value == null) '-D$name' else '-D$name=$value',
150166
],

pkgs/native_toolchain_c/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: native_toolchain_c
22
description: >-
33
A library to invoke the native C compiler installed on the host machine.
4-
version: 0.2.1
4+
version: 0.2.2
55
repository: https://github.com/dart-lang/native/tree/main/pkgs/native_toolchain_c
66

77
topics:

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_android_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void main() {
4141

4242
for (final linkMode in LinkMode.values) {
4343
for (final target in targets) {
44-
test('Cbuilder $linkMode library $target', () async {
44+
test('CBuilder $linkMode library $target', () async {
4545
await inTempDir((tempUri) async {
4646
final libUri = await buildLib(
4747
tempUri,
@@ -77,7 +77,7 @@ void main() {
7777
}
7878
}
7979

80-
test('Cbuilder API levels binary difference', () async {
80+
test('CBuilder API levels binary difference', () async {
8181
const target = Target.androidArm64;
8282
const linkMode = LinkMode.dynamic;
8383
const apiLevel1 = flutterAndroidNdkVersionLowestSupported;

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_ios_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void main() {
5050
Uri.file('@executable_path/Frameworks/$libName'),
5151
]) {
5252
test(
53-
'Cbuilder $linkMode library $targetIOSSdk $target'
53+
'CBuilder $linkMode library $targetIOSSdk $target'
5454
' ${installName ?? ''}'
5555
.trim(), () async {
5656
await inTempDir((tempUri) async {

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_linux_host_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void main() {
3636

3737
for (final linkMode in LinkMode.values) {
3838
for (final target in targets) {
39-
test('Cbuilder $linkMode library $target', () async {
39+
test('CBuilder $linkMode library $target', () async {
4040
await inTempDir((tempUri) async {
4141
final addCUri =
4242
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_macos_host_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void main() {
3636

3737
for (final linkMode in LinkMode.values) {
3838
for (final target in targets) {
39-
test('Cbuilder $linkMode library $target', () async {
39+
test('CBuilder $linkMode library $target', () async {
4040
await inTempDir((tempUri) async {
4141
final addCUri =
4242
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');

pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void main() {
4848

4949
for (final linkMode in LinkMode.values) {
5050
for (final target in targets) {
51-
test('Cbuilder $linkMode library $target', () async {
51+
test('CBuilder $linkMode library $target', () async {
5252
await inTempDir((tempUri) async {
5353
final addCUri =
5454
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');

0 commit comments

Comments
 (0)