Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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