Skip to content

Optional .a linkage for libraries #3697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
84 changes: 53 additions & 31 deletions arduino-core/src/processing/app/debug/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -1070,8 +1070,23 @@ private void compileLibrary(UserLibrary lib, List<File> includeFolders)
if (lib.useRecursion()) {
// libBuildFolder == {build.path}/LibName
// libFolder == {lib.path}/src
recursiveCompileFilesInFolder(libBuildFolder, libFolder, includeFolders);


// Compile the library with .a linkage if a flag was set in library.properties
if(lib.alinkage()){

createFolder(libBuildFolder);
File afile = compileThroughAFile(libBuildFolder, libFolder, lib.getName(), includeFolders);

// This is not a .o object file, but a .a file with all .o files inside.
// This way libraries can be optimized better, similar as the core files.
objectFiles.add(afile);
}

// no alinkage, old, default .o file linkage
else{
recursiveCompileFilesInFolder(libBuildFolder, libFolder, includeFolders);
}

} else {
// libFolder == {lib.path}/
// utilityFolder == {lib.path}/utility
Expand Down Expand Up @@ -1103,39 +1118,17 @@ private void compileFilesInFolder(File buildFolder, File srcFolder, List<File> i
objectFiles.addAll(objects);
}

// 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file.
// Also compiles the variant (if it supplies actual source files),
// which are included in the link directly (not through core.a)
void compileCore()
throws RunnerException, PreferencesMapException {

File coreFolder = prefs.getFile("build.core.path");
File variantFolder = prefs.getFile("build.variant.path");
File buildFolder = new File(prefs.getFile("build.path"), "core");
if (!buildFolder.exists() && !buildFolder.mkdirs()) {
throw new RunnerException("Unable to create folder " + buildFolder);
}
private File compileThroughAFile(File buildFolder, File srcFolder, String name, List<File> includeFolders)
throws RunnerException, PreferencesMapException {
File afile = new File(buildFolder, name + ".a");

List<File> includeFolders = new ArrayList<File>();
includeFolders.add(coreFolder); // include core path only
if (variantFolder != null)
includeFolders.add(variantFolder);


if (variantFolder != null)
objectFiles.addAll(compileFiles(buildFolder, variantFolder, true,
includeFolders));

File afile = new File(buildFolder, "core.a");

List<File> coreObjectFiles = compileFiles(buildFolder, coreFolder, true,
List<File> aObjectFiles = compileFiles(buildFolder, srcFolder, true,
includeFolders);

// See if the .a file is already uptodate
if (afile.exists()) {
boolean changed = false;
for (File file : coreObjectFiles) {
for (File file : aObjectFiles) {
if (file.lastModified() > afile.lastModified()) {
changed = true;
break;
Expand All @@ -1151,15 +1144,15 @@ void compileCore()
if (!changed) {
if (verbose)
System.out.println(I18n.format(tr("Using previously compiled file: {0}"), afile.getPath()));
return;
return afile;
}
}

// Delete the .a file, to prevent any previous code from lingering
afile.delete();

try {
for (File file : coreObjectFiles) {
for (File file : aObjectFiles) {

PreferencesMap dict = new PreferencesMap(prefs);
dict.put("ide_version", "" + BaseNoGui.REVISION);
Expand All @@ -1180,6 +1173,35 @@ void compileCore()
afile.delete();
throw e;
}

return afile;
}

// 3. compile the core, outputting .o files to <buildPath> and then
// collecting them into the core.a library file.
// Also compiles the variant (if it supplies actual source files),
// which are included in the link directly (not through core.a)
void compileCore()
throws RunnerException, PreferencesMapException {

File coreFolder = prefs.getFile("build.core.path");
File variantFolder = prefs.getFile("build.variant.path");
File buildFolder = new File(prefs.getFile("build.path"), "core");
if (!buildFolder.exists() && !buildFolder.mkdirs()) {
throw new RunnerException("Unable to create folder " + buildFolder);
}

List<File> includeFolders = new ArrayList<File>();
includeFolders.add(coreFolder); // include core path only
if (variantFolder != null)
includeFolders.add(variantFolder);


if (variantFolder != null)
objectFiles.addAll(compileFiles(buildFolder, variantFolder, true,
includeFolders));

compileThroughAFile(buildFolder, coreFolder, "core", includeFolders);
}

// 4. link it all together into the .elf file
Expand Down
12 changes: 12 additions & 0 deletions arduino-core/src/processing/app/packages/UserLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class UserLibrary extends ContributedLibrary {
private List<String> types;
private List<String> declaredTypes;
private boolean onGoingDevelopment;
private boolean alinkage;

private static final List<String> MANDATORY_PROPERTIES = Arrays
.asList("name", "version", "author", "maintainer",
Expand Down Expand Up @@ -154,6 +155,12 @@ public static UserLibrary create(File libFolder) throws IOException {
typesList.add(type.trim());
}

String alinkageString = properties.get("alinkage");
boolean alinkage = false;
if(alinkageString != null && alinkageString.equals("true")) {
alinkage = true;
}

UserLibrary res = new UserLibrary();
res.setInstalledFolder(libFolder);
res.setInstalled(true);
Expand All @@ -170,6 +177,7 @@ public static UserLibrary create(File libFolder) throws IOException {
res.layout = layout;
res.declaredTypes = typesList;
res.onGoingDevelopment = Files.exists(Paths.get(libFolder.getAbsolutePath(), Constants.LIBRARY_DEVELOPMENT_FLAG_FILE));
res.alinkage = alinkage;
return res;
}

Expand Down Expand Up @@ -274,6 +282,10 @@ public boolean onGoingDevelopment() {
return onGoingDevelopment;
}

public boolean alinkage() {
return alinkage;
}

protected enum LibraryLayout {
FLAT, RECURSIVE
}
Expand Down