Skip to content

Commit

Permalink
[native_toolchain_c] Default handling for PIC/PIE compiler flags (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
blaugold authored Sep 6, 2023
1 parent 0a4e5f8 commit 387f894
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 107 deletions.
5 changes: 5 additions & 0 deletions pkgs/native_toolchain_c/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.2.2

- Generate position independent code for libraries by default and add
`pic` option to control this behavior.

## 0.2.1

- Added `defines` for specifying custom defines.
Expand Down
20 changes: 19 additions & 1 deletion pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ class CBuilder implements Builder {
/// Defaults to `true`.
final bool ndebugDefine;

/// Whether the compiler will emit position independent code.
///
/// When set to `true`, libraries will be compiled with `-fPIC` and
/// executables with `-fPIE`. Accordingly the corresponding parameter of the
/// [executable] constructor is named `pie`.
///
/// When set to `null`, the default behavior of the compiler will be used.
///
/// This option has no effect when building for Windows, where generation of
/// position independent code is not configurable.
///
/// Defaults to `true` for libraries and `false` for executables.
final bool? pic;

CBuilder.library({
required this.name,
required this.assetId,
Expand All @@ -90,6 +104,7 @@ class CBuilder implements Builder {
this.defines = const {},
this.buildModeDefine = true,
this.ndebugDefine = true,
this.pic = true,
}) : _type = _CBuilderType.library;

CBuilder.executable({
Expand All @@ -99,9 +114,11 @@ class CBuilder implements Builder {
this.defines = const {},
this.buildModeDefine = true,
this.ndebugDefine = true,
bool? pie = false,
}) : _type = _CBuilderType.executable,
assetId = null,
installName = null;
installName = null,
pic = pie;

/// Runs the C Compiler with on this C build spec.
///
Expand Down Expand Up @@ -148,6 +165,7 @@ class CBuilder implements Builder {
if (ndebugDefine && buildConfig.buildMode != BuildMode.debug)
'NDEBUG': null,
},
pic: pic,
);
await task.run();
}
Expand Down
18 changes: 17 additions & 1 deletion pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ class RunCBuilder {
final Uri outDir;
final Target target;

/// The install of the [dynamicLibrary].
/// The install name of the [dynamicLibrary].
///
/// Can be inspected with `otool -D <path-to-dylib>`.
///
/// Can be modified with `install_name_tool`.
final Uri? installName;

final Map<String, String?> defines;
final bool? pic;

RunCBuilder({
required this.buildConfig,
Expand All @@ -43,6 +44,7 @@ class RunCBuilder {
this.staticLibrary,
this.installName,
this.defines = const {},
this.pic,
}) : outDir = buildConfig.outDir,
target = buildConfig.target,
assert([executable, dynamicLibrary, staticLibrary]
Expand Down Expand Up @@ -145,6 +147,20 @@ class RunCBuilder {
'-o',
outDir.resolve('out.o').toFilePath(),
],
if (pic != null)
if (pic!) ...[
if (dynamicLibrary != null) '-fPIC',
// Using PIC for static libraries allows them to be linked into
// any executable, but it is not necessarily the best option in
// terms of overhead. We would have to know wether the target into
// which the static library is linked is PIC, PIE or neither. Then
// we could use the same option for the static library.
if (staticLibrary != null) '-fPIC',
if (executable != null) '-fPIE',
] else ...[
'-fno-PIC',
'-fno-PIE',
],
for (final MapEntry(key: name, :value) in defines.entries)
if (value == null) '-D$name' else '-D$name=$value',
],
Expand Down
2 changes: 1 addition & 1 deletion pkgs/native_toolchain_c/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: native_toolchain_c
description: >-
A library to invoke the native C compiler installed on the host machine.
version: 0.2.1
version: 0.2.2
repository: https://github.com/dart-lang/native/tree/main/pkgs/native_toolchain_c

topics:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void main() {

for (final linkMode in LinkMode.values) {
for (final target in targets) {
test('Cbuilder $linkMode library $target', () async {
test('CBuilder $linkMode library $target', () async {
await inTempDir((tempUri) async {
final libUri = await buildLib(
tempUri,
Expand Down Expand Up @@ -77,7 +77,7 @@ void main() {
}
}

test('Cbuilder API levels binary difference', () async {
test('CBuilder API levels binary difference', () async {
const target = Target.androidArm64;
const linkMode = LinkMode.dynamic;
const apiLevel1 = flutterAndroidNdkVersionLowestSupported;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void main() {
Uri.file('@executable_path/Frameworks/$libName'),
]) {
test(
'Cbuilder $linkMode library $targetIOSSdk $target'
'CBuilder $linkMode library $targetIOSSdk $target'
' ${installName ?? ''}'
.trim(), () async {
await inTempDir((tempUri) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void main() {

for (final linkMode in LinkMode.values) {
for (final target in targets) {
test('Cbuilder $linkMode library $target', () async {
test('CBuilder $linkMode library $target', () async {
await inTempDir((tempUri) async {
final addCUri =
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void main() {

for (final linkMode in LinkMode.values) {
for (final target in targets) {
test('Cbuilder $linkMode library $target', () async {
test('CBuilder $linkMode library $target', () async {
await inTempDir((tempUri) async {
final addCUri =
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void main() {

for (final linkMode in LinkMode.values) {
for (final target in targets) {
test('Cbuilder $linkMode library $target', () async {
test('CBuilder $linkMode library $target', () async {
await inTempDir((tempUri) async {
final addCUri =
packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
Expand Down
Loading

0 comments on commit 387f894

Please sign in to comment.