am f7ffcaa7: Merge "Build the split-select tool without C++11 support" into lmp-mr1-dev

* commit 'f7ffcaa7a478eaafc121e84b14dcaf2503dd5457':
  Build the split-select tool without C++11 support
This commit is contained in:
Adam Lesinski
2014-11-04 01:01:13 +00:00
committed by Android Git Automerger
11 changed files with 210 additions and 121 deletions

View File

@@ -14,9 +14,11 @@
* limitations under the License.
*/
#ifndef __AAPT_UTIL_H
#define __AAPT_UTIL_H
#ifndef H_AAPT_UTIL
#define H_AAPT_UTIL
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -25,6 +27,38 @@ namespace AaptUtil {
android::Vector<android::String8> split(const android::String8& str, const char sep);
android::Vector<android::String8> splitAndLowerCase(const android::String8& str, const char sep);
template <typename KEY, typename VALUE>
void appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,
const KEY& key, const VALUE& value);
template <typename KEY, typename VALUE>
void appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,
const KEY& key, const VALUE& value);
//
// Implementations
//
template <typename KEY, typename VALUE>
void appendValue(android::KeyedVector<KEY, android::Vector<VALUE> >& keyedVector,
const KEY& key, const VALUE& value) {
ssize_t idx = keyedVector.indexOfKey(key);
if (idx < 0) {
idx = keyedVector.add(key, android::Vector<VALUE>());
}
keyedVector.editValueAt(idx).add(value);
}
template <typename KEY, typename VALUE>
void appendValue(android::KeyedVector<KEY, android::SortedVector<VALUE> >& keyedVector,
const KEY& key, const VALUE& value) {
ssize_t idx = keyedVector.indexOfKey(key);
if (idx < 0) {
idx = keyedVector.add(key, android::SortedVector<VALUE>());
}
keyedVector.editValueAt(idx).add(value);
}
} // namespace AaptUtil
#endif // __AAPT_UTIL_H
#endif // H_AAPT_UTIL

View File

@@ -16,42 +16,58 @@
#include "Abi.h"
using namespace android;
namespace split {
namespace abi {
static const std::vector<Variant> sNoneVariants = {};
static const std::vector<Variant> sArmVariants =
{Variant::armeabi, Variant::armeabi_v7a, Variant::arm64_v8a};
static const std::vector<Variant> sIntelVariants = {Variant::x86, Variant::x86_64};
static const std::vector<Variant> sMipsVariants = {Variant::mips, Variant::mips64};
static Vector<Variant> buildVariants(Variant v1, Variant v2) {
Vector<Variant> v;
v.add(v1);
v.add(v2);
return v;
}
static Vector<Variant> buildVariants(Variant v1, Variant v2, Variant v3) {
Vector<Variant> v;
v.add(v1);
v.add(v2);
v.add(v3);
return v;
}
static const Vector<Variant> sNoneVariants;
static const Vector<Variant> sArmVariants = buildVariants(Variant_armeabi, Variant_armeabi_v7a, Variant_arm64_v8a);
static const Vector<Variant> sIntelVariants = buildVariants(Variant_x86, Variant_x86_64);
static const Vector<Variant> sMipsVariants = buildVariants(Variant_mips, Variant_mips64);
Family getFamily(Variant variant) {
switch (variant) {
case Variant::none:
return Family::none;
case Variant::armeabi:
case Variant::armeabi_v7a:
case Variant::arm64_v8a:
return Family::arm;
case Variant::x86:
case Variant::x86_64:
return Family::intel;
case Variant::mips:
case Variant::mips64:
return Family::mips;
case Variant_none:
return Family_none;
case Variant_armeabi:
case Variant_armeabi_v7a:
case Variant_arm64_v8a:
return Family_arm;
case Variant_x86:
case Variant_x86_64:
return Family_intel;
case Variant_mips:
case Variant_mips64:
return Family_mips;
}
return Family::none;
return Family_none;
}
const std::vector<Variant>& getVariants(Family family) {
const Vector<Variant>& getVariants(Family family) {
switch (family) {
case Family::none:
case Family_none:
return sNoneVariants;
case Family::arm:
case Family_arm:
return sArmVariants;
case Family::intel:
case Family_intel:
return sIntelVariants;
case Family::mips:
case Family_mips:
return sMipsVariants;
}
return sNoneVariants;
@@ -59,21 +75,21 @@ const std::vector<Variant>& getVariants(Family family) {
const char* toString(Variant variant) {
switch (variant) {
case Variant::none:
case Variant_none:
return "";
case Variant::armeabi:
case Variant_armeabi:
return "armeabi";
case Variant::armeabi_v7a:
case Variant_armeabi_v7a:
return "armeabi-v7a";
case Variant::arm64_v8a:
case Variant_arm64_v8a:
return "arm64-v8a";
case Variant::x86:
case Variant_x86:
return "x86";
case Variant::x86_64:
case Variant_x86_64:
return "x86_64";
case Variant::mips:
case Variant_mips:
return "mips";
case Variant::mips64:
case Variant_mips64:
return "mips64";
}
return "";

View File

@@ -17,31 +17,31 @@
#ifndef H_ANDROID_SPLIT_ABI
#define H_ANDROID_SPLIT_ABI
#include <vector>
#include <utils/Vector.h>
namespace split {
namespace abi {
enum class Variant {
none = 0,
armeabi,
armeabi_v7a,
arm64_v8a,
x86,
x86_64,
mips,
mips64,
enum Variant {
Variant_none = 0,
Variant_armeabi,
Variant_armeabi_v7a,
Variant_arm64_v8a,
Variant_x86,
Variant_x86_64,
Variant_mips,
Variant_mips64,
};
enum class Family {
none,
arm,
intel,
mips,
enum Family {
Family_none,
Family_arm,
Family_intel,
Family_mips,
};
Family getFamily(Variant variant);
const std::vector<Variant>& getVariants(Family family);
const android::Vector<Variant>& getVariants(Family family);
const char* toString(Variant variant);
} // namespace abi

View File

@@ -17,10 +17,6 @@
# This tool is prebuilt if we're doing an app-only build.
ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
# TODO(adamlesinski): Enable OS X builds when I figure out how
# to build with clang and libc++
ifneq ($(HOST_OS),darwin)
# ==========================================================
# Setup some common variables for the different build
# targets here.
@@ -55,7 +51,7 @@ hostStaticLibs := \
libexpat \
libziparchive-host
cFlags := -std=c++11 -Wall -Werror
cFlags := -Wall -Werror
ifeq ($(HOST_OS),linux)
hostLdLibs += -lrt -ldl -lpthread
@@ -115,5 +111,4 @@ LOCAL_CFLAGS += $(cFlags)
include $(BUILD_HOST_EXECUTABLE)
endif # Not OS X
endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK

View File

@@ -16,25 +16,17 @@
#include "Grouper.h"
#include "aapt/AaptUtil.h"
#include "SplitDescription.h"
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
using namespace android;
using AaptUtil::appendValue;
namespace split {
template <typename Key, typename Value>
static void addToVector(KeyedVector<Key, SortedVector<Value> >& group,
const Key& key, const Value& value) {
ssize_t idx = group.indexOfKey(key);
if (idx < 0) {
idx = group.add(key, SortedVector<Value>());
}
group.editValueAt(idx).add(value);
}
Vector<SortedVector<SplitDescription> >
groupByMutualExclusivity(const Vector<SplitDescription>& splits) {
Vector<SortedVector<SplitDescription> > groups;
@@ -43,20 +35,22 @@ groupByMutualExclusivity(const Vector<SplitDescription>& splits) {
KeyedVector<SplitDescription, SortedVector<SplitDescription> > densityGroups;
KeyedVector<SplitDescription, SortedVector<SplitDescription> > abiGroups;
KeyedVector<SplitDescription, SortedVector<SplitDescription> > localeGroups;
for (const SplitDescription& split : splits) {
const size_t splitCount = splits.size();
for (size_t i = 0; i < splitCount; i++) {
const SplitDescription& split = splits[i];
if (split.config.density != 0) {
SplitDescription key(split);
key.config.density = 0;
key.config.sdkVersion = 0; // Ignore density so we can support anydpi.
addToVector(densityGroups, key, split);
} else if (split.abi != abi::Variant::none) {
appendValue(densityGroups, key, split);
} else if (split.abi != abi::Variant_none) {
SplitDescription key(split);
key.abi = abi::Variant::none;
addToVector(abiGroups, key, split);
key.abi = abi::Variant_none;
appendValue(abiGroups, key, split);
} else if (split.config.locale != 0) {
SplitDescription key(split);
key.config.clearLocale();
addToVector(localeGroups, key, split);
appendValue(localeGroups, key, split);
} else {
groups.add();
groups.editTop().add(split);

View File

@@ -19,7 +19,6 @@
#include "SplitDescription.h"
#include <gtest/gtest.h>
#include <initializer_list>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -55,7 +54,11 @@ protected:
}
void addSplit(Vector<SplitDescription>& splits, const char* str);
void expectHasGroupWithSplits(std::initializer_list<const char*> l);
void expectHasGroupWithSplits(const char* a);
void expectHasGroupWithSplits(const char* a, const char* b);
void expectHasGroupWithSplits(const char* a, const char* b, const char* c);
void expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d);
void expectHasGroupWithSplits(const Vector<const char*>& expectedStrs);
Vector<SortedVector<SplitDescription> > mGroups;
};
@@ -65,39 +68,70 @@ TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) {
}
TEST_F(GrouperTest, shouldGroupDensities) {
expectHasGroupWithSplits({"en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi"});
expectHasGroupWithSplits({"en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi"});
expectHasGroupWithSplits({"fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi"});
expectHasGroupWithSplits({"hdpi", "xhdpi", "xxhdpi", "anydpi"});
expectHasGroupWithSplits("en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi");
expectHasGroupWithSplits("en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi");
expectHasGroupWithSplits("fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi");
expectHasGroupWithSplits("hdpi", "xhdpi", "xxhdpi", "anydpi");
}
TEST_F(GrouperTest, shouldGroupAbi) {
expectHasGroupWithSplits({":armeabi", ":x86"});
expectHasGroupWithSplits(":armeabi", ":x86");
}
TEST_F(GrouperTest, shouldGroupLocale) {
expectHasGroupWithSplits({"pl-rPL", "de-rDE"});
expectHasGroupWithSplits("pl-rPL", "de-rDE");
}
TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) {
expectHasGroupWithSplits({"large"});
expectHasGroupWithSplits({"xlarge"});
expectHasGroupWithSplits({"v7"});
expectHasGroupWithSplits({"v8"});
expectHasGroupWithSplits({"sw600dp"});
expectHasGroupWithSplits({"sw300dp"});
expectHasGroupWithSplits("large");
expectHasGroupWithSplits("xlarge");
expectHasGroupWithSplits("v7");
expectHasGroupWithSplits("v8");
expectHasGroupWithSplits("sw600dp");
expectHasGroupWithSplits("sw300dp");
}
//
// Helper methods
//
void GrouperTest::expectHasGroupWithSplits(std::initializer_list<const char*> l) {
void GrouperTest::expectHasGroupWithSplits(const char* a) {
Vector<const char*> expected;
expected.add(a);
expectHasGroupWithSplits(expected);
}
void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b) {
Vector<const char*> expected;
expected.add(a);
expected.add(b);
expectHasGroupWithSplits(expected);
}
void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c) {
Vector<const char*> expected;
expected.add(a);
expected.add(b);
expected.add(c);
expectHasGroupWithSplits(expected);
}
void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d) {
Vector<const char*> expected;
expected.add(a);
expected.add(b);
expected.add(c);
expected.add(d);
expectHasGroupWithSplits(expected);
}
void GrouperTest::expectHasGroupWithSplits(const Vector<const char*>& expectedStrs) {
Vector<SplitDescription> splits;
for (const char* str : l) {
const size_t expectedStrCount = expectedStrs.size();
for (size_t i = 0; i < expectedStrCount; i++) {
splits.add();
if (!SplitDescription::parse(String8(str), &splits.editTop())) {
ADD_FAILURE() << "Failed to parse SplitDescription " << str;
if (!SplitDescription::parse(String8(expectedStrs[i]), &splits.editTop())) {
ADD_FAILURE() << "Failed to parse SplitDescription " << expectedStrs[i];
return;
}
}

View File

@@ -63,7 +63,7 @@ static void help() {
class SplitSelector {
public:
SplitSelector() = default;
SplitSelector();
SplitSelector(const Vector<SplitDescription>& splits);
Vector<SplitDescription> getBestSplits(const SplitDescription& target) const;
@@ -75,6 +75,9 @@ private:
Vector<SortedVector<SplitDescription> > mGroups;
};
SplitSelector::SplitSelector() {
}
SplitSelector::SplitSelector(const Vector<SplitDescription>& splits)
: mGroups(groupByMutualExclusivity(splits)) {
}

View File

@@ -65,12 +65,12 @@ sp<Rule> RuleGenerator::generateDensity(const Vector<int>& allDensities, size_t
sp<Rule> RuleGenerator::generateAbi(const Vector<abi::Variant>& splitAbis, size_t index) {
const abi::Variant thisAbi = splitAbis[index];
const std::vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi));
const Vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi));
std::vector<abi::Variant>::const_iterator start =
Vector<abi::Variant>::const_iterator start =
std::find(familyVariants.begin(), familyVariants.end(), thisAbi);
std::vector<abi::Variant>::const_iterator end = familyVariants.end();
Vector<abi::Variant>::const_iterator end = familyVariants.end();
if (index + 1 < splitAbis.size()) {
end = std::find(start, familyVariants.end(), splitAbis[index + 1]);
}
@@ -127,7 +127,7 @@ sp<Rule> RuleGenerator::generate(const SortedVector<SplitDescription>& group, si
rootRule->subrules.add(generateDensity(allDensities, densityIndex));
}
if (group[index].abi != abi::Variant::none) {
if (group[index].abi != abi::Variant_none) {
size_t abiIndex = 0;
Vector<abi::Variant> allVariants;
allVariants.add(group[index].abi);

View File

@@ -25,19 +25,19 @@ using namespace android;
namespace split {
static void expectDensityRule(const Vector<int>& densities, int density, int greaterThan, int lessThan);
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant,
std::initializer_list<const char*> matches);
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a);
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a, const char* b);
TEST(RuleGeneratorTest, testAbiRules) {
Vector<abi::Variant> abis;
abis.add(abi::Variant::armeabi);
abis.add(abi::Variant::armeabi_v7a);
abis.add(abi::Variant::x86);
abis.add(abi::Variant_armeabi);
abis.add(abi::Variant_armeabi_v7a);
abis.add(abi::Variant_x86);
std::sort(abis.begin(), abis.end());
expectAbiRule(abis, abi::Variant::armeabi, {"armeabi"});
expectAbiRule(abis, abi::Variant::armeabi_v7a, {"armeabi-v7a", "arm64-v8a"});
expectAbiRule(abis, abi::Variant::x86, {"x86", "x86_64"});
expectAbiRule(abis, abi::Variant_armeabi, "armeabi");
expectAbiRule(abis, abi::Variant_armeabi_v7a, "armeabi-v7a", "arm64-v8a");
expectAbiRule(abis, abi::Variant_x86, "x86", "x86_64");
}
TEST(RuleGeneratorTest, testDensityRules) {
@@ -126,8 +126,7 @@ static void expectDensityRule(const Vector<int>& densities, int density, int gre
}
}
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant,
std::initializer_list<const char*> matches) {
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const Vector<const char*>& matches) {
const abi::Variant* iter = std::find(abis.begin(), abis.end(), variant);
if (abis.end() == iter) {
ADD_FAILURE() << abi::toString(variant) << " was not in the abi list.";
@@ -143,7 +142,9 @@ static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant
EXPECT_EQ(matches.size(), rule->stringArgs.size())
<< " for " << abi::toString(variant) << " rule";
for (const char* match : matches) {
const size_t matchCount = matches.size();
for (size_t i = 0; i < matchCount; i++) {
const char* match = matches[i];
if (rule->stringArgs.end() ==
std::find(rule->stringArgs.begin(), rule->stringArgs.end(), String8(match))) {
ADD_FAILURE() << "Rule for abi " << abi::toString(variant)
@@ -152,4 +153,17 @@ static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant
}
}
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a) {
Vector<const char*> matches;
matches.add(a);
expectAbiRule(abis, variant, matches);
}
static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, const char* a, const char* b) {
Vector<const char*> matches;
matches.add(a);
matches.add(b);
expectAbiRule(abis, variant, matches);
}
} // namespace split

View File

@@ -27,7 +27,7 @@ using namespace android;
namespace split {
SplitDescription::SplitDescription()
: abi(abi::Variant::none) {
: abi(abi::Variant_none) {
}
int SplitDescription::compare(const SplitDescription& rhs) const {
@@ -38,11 +38,11 @@ int SplitDescription::compare(const SplitDescription& rhs) const {
}
bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescription& target) const {
if (abi != abi::Variant::none || o.abi != abi::Variant::none) {
if (abi != abi::Variant_none || o.abi != abi::Variant_none) {
abi::Family family = abi::getFamily(abi);
abi::Family oFamily = abi::getFamily(o.abi);
if (family != oFamily) {
return family != abi::Family::none;
return family != abi::Family_none;
}
if (int(target.abi) - int(abi) < int(target.abi) - int(o.abi)) {
@@ -53,7 +53,7 @@ bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescri
}
bool SplitDescription::match(const SplitDescription& o) const {
if (abi != abi::Variant::none) {
if (abi != abi::Variant_none) {
abi::Family family = abi::getFamily(abi);
abi::Family oFamily = abi::getFamily(o.abi);
if (family != oFamily) {
@@ -69,7 +69,7 @@ bool SplitDescription::match(const SplitDescription& o) const {
String8 SplitDescription::toString() const {
String8 extension;
if (abi != abi::Variant::none) {
if (abi != abi::Variant_none) {
if (extension.isEmpty()) {
extension.append(":");
} else {
@@ -85,40 +85,40 @@ String8 SplitDescription::toString() const {
ssize_t parseAbi(const Vector<String8>& parts, const ssize_t index,
SplitDescription* outSplit) {
const ssize_t N = parts.size();
abi::Variant abi = abi::Variant::none;
abi::Variant abi = abi::Variant_none;
ssize_t endIndex = index;
if (parts[endIndex] == "arm64") {
endIndex++;
if (endIndex < N) {
if (parts[endIndex] == "v8a") {
endIndex++;
abi = abi::Variant::arm64_v8a;
abi = abi::Variant_arm64_v8a;
}
}
} else if (parts[endIndex] == "armeabi") {
endIndex++;
abi = abi::Variant::armeabi;
abi = abi::Variant_armeabi;
if (endIndex < N) {
if (parts[endIndex] == "v7a") {
endIndex++;
abi = abi::Variant::armeabi_v7a;
abi = abi::Variant_armeabi_v7a;
}
}
} else if (parts[endIndex] == "x86") {
endIndex++;
abi = abi::Variant::x86;
abi = abi::Variant_x86;
} else if (parts[endIndex] == "x86_64") {
endIndex++;
abi = abi::Variant::x86_64;
abi = abi::Variant_x86_64;
} else if (parts[endIndex] == "mips") {
endIndex++;
abi = abi::Variant::mips;
abi = abi::Variant_mips;
} else if (parts[endIndex] == "mips64") {
endIndex++;
abi = abi::Variant::mips64;
abi = abi::Variant_mips64;
}
if (abi == abi::Variant::none && endIndex != index) {
if (abi == abi::Variant_none && endIndex != index) {
return -1;
}

View File

@@ -27,7 +27,6 @@ namespace split {
struct SplitDescription {
SplitDescription();
SplitDescription(const SplitDescription&) = default;
ConfigDescription config;
abi::Variant abi;