Merge "AAPT2: Enable windows build and make sure it builds" into nyc-dev

This commit is contained in:
Adam Lesinski
2016-04-07 17:03:54 +00:00
committed by Android (Google) Code Review
17 changed files with 133 additions and 86 deletions

View File

@@ -131,33 +131,40 @@ hostStaticLibs := \
libbase \
libprotobuf-cpp-lite_static
# Do not add any shared libraries. AAPT2 is built to run on many
# environments that may not have the required dependencies.
hostSharedLibs :=
ifneq ($(strip $(USE_MINGW)),)
hostStaticLibs += libz
else
hostLdLibs += -lz
endif
# Statically link libz for MinGW (Win SDK under Linux),
# and dynamically link for all others.
hostStaticLibs_windows := libz
hostLdLibs_linux := -lz
hostLdLibs_darwin := -lz
cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
cppFlags := -std=c++14 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
cFlags_darwin := -D_DARWIN_UNLIMITED_STREAMS
cFlags_windows := -Wno-maybe-uninitialized # Incorrectly marking use of Maybe.value() as error.
cppFlags := -std=c++11 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST)
# ==========================================================
# NOTE: Do not add any shared libraries.
# AAPT2 is built to run on many environments
# that may not have the required dependencies.
# ==========================================================
# ==========================================================
# Build the host static library: libaapt2
# ==========================================================
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libaapt2
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(sources)
LOCAL_STATIC_LIBRARIES += $(hostStaticLibs)
LOCAL_CFLAGS += $(cFlags)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
LOCAL_STATIC_LIBRARIES := $(hostStaticLibs)
LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
include $(BUILD_HOST_STATIC_LIBRARY)
# ==========================================================
@@ -166,16 +173,18 @@ include $(BUILD_HOST_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libaapt2_tests
LOCAL_MODULE_TAGS := tests
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(testSources)
LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
LOCAL_LDLIBS += $(hostLdLibs)
LOCAL_CFLAGS += $(cFlags)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
LOCAL_LDLIBS := $(hostLdLibs)
LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
include $(BUILD_HOST_NATIVE_TEST)
# ==========================================================
@@ -183,16 +192,18 @@ include $(BUILD_HOST_NATIVE_TEST)
# ==========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := aapt2
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(cFlags)
LOCAL_CFLAGS_darwin := $(cFlags_darwin)
LOCAL_CFLAGS_windows := $(cFlags_windows)
LOCAL_CPPFLAGS := $(cppFlags)
LOCAL_C_INCLUDES := $(protoIncludes)
LOCAL_SRC_FILES := $(main) $(toolSources)
LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
LOCAL_LDLIBS += $(hostLdLibs)
LOCAL_CFLAGS += $(cFlags)
LOCAL_CPPFLAGS += $(cppFlags)
LOCAL_C_INCLUDES += $(protoIncludes)
LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
LOCAL_LDLIBS := $(hostLdLibs)
LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
LOCAL_LDLIBS_linux := $(hostLdLibs_linux)
include $(BUILD_HOST_EXECUTABLE)
ifeq ($(ONE_SHOT_MAKEFILE),)

View File

@@ -20,8 +20,6 @@
#include <gtest/gtest.h>
#include <string>
using namespace android;
namespace aapt {
TEST(StringPoolTest, InsertOneString) {
@@ -171,24 +169,28 @@ TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
}
TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool;
BigBuffer buffer(1024);
StringPool::flattenUtf8(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
android::ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
}
TEST(StringPoolTest, FlattenOddCharactersUtf16) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool;
pool.makeRef(u"\u093f");
BigBuffer buffer(1024);
StringPool::flattenUtf16(&buffer, pool);
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
android::ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
size_t len = 0;
const char16_t* str = test.stringAt(0, &len);
EXPECT_EQ(1u, len);
@@ -199,6 +201,8 @@ TEST(StringPoolTest, FlattenOddCharactersUtf16) {
constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。";
TEST(StringPoolTest, FlattenUtf8) {
using namespace android; // For NO_ERROR on Windows.
StringPool pool;
StringPool::Ref ref1 = pool.makeRef(u"hello");
@@ -219,8 +223,8 @@ TEST(StringPoolTest, FlattenUtf8) {
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
{
android::ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR);
ResStringPool test;
ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
EXPECT_EQ(util::getString(test, 0), u"hello");
EXPECT_EQ(util::getString(test, 1), u"goodbye");

View File

@@ -20,6 +20,8 @@
#include "compile/PseudolocaleGenerator.h"
#include "compile/Pseudolocalizer.h"
#include <algorithm>
namespace aapt {
std::unique_ptr<StyledString> pseudolocalizeStyledString(StyledString* string,

View File

@@ -24,6 +24,7 @@
#include "util/BigBuffer.h"
#include <android-base/macros.h>
#include <algorithm>
#include <type_traits>
#include <numeric>

View File

@@ -21,6 +21,7 @@
#include "xml/XmlDom.h"
#include <androidfw/ResourceTypes.h>
#include <algorithm>
#include <utils/misc.h>
#include <vector>

View File

@@ -46,6 +46,8 @@ public:
::testing::AssertionResult flatten(xml::XmlResource* doc, android::ResXMLTree* outTree,
XmlFlattenerOptions options = {}) {
using namespace android; // For NO_ERROR on windows because it is a macro.
BigBuffer buffer(1024);
XmlFlattener flattener(&buffer, options);
if (!flattener.consume(mContext.get(), doc)) {
@@ -53,7 +55,7 @@ public:
}
std::unique_ptr<uint8_t[]> data = util::copy(buffer);
if (outTree->setTo(data.get(), buffer.size(), true) != android::NO_ERROR) {
if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) {
return ::testing::AssertionFailure() << "flattened XML is corrupt";
}
return ::testing::AssertionSuccess();

View File

@@ -49,16 +49,18 @@ struct AnnotationProcessorTest : public ::testing::Test {
};
TEST_F(AnnotationProcessorTest, EmitsDeprecated) {
ASSERT_TRUE(parse(R"EOF(
const char* xmlInput = R"EOF(
<resources>
<declare-styleable name="foo">
<declare-styleable name="foo">
<!-- Some comment, and it should contain
a marker word, something that marks
this resource as nor needed.
{@deprecated That's the marker! } -->
<attr name="autoText" format="boolean" />
</declare-styleable>
</resources>)EOF"));
</resources>)EOF";
ASSERT_TRUE(parse(xmlInput));
Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText");
ASSERT_NE(nullptr, attr);

View File

@@ -318,7 +318,7 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package
}
std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>(
sortedAttributes[i].fieldName, i);
sortedAttributes[i].fieldName, static_cast<uint32_t>(i));
AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder();

View File

@@ -239,13 +239,15 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) {
ASSERT_TRUE(generator.generate(u"android", &out));
std::string actual = out.str();
EXPECT_NE(std::string::npos, actual.find(
R"EOF(/**
const char* expectedText =
R"EOF(/**
* This is a comment
* @deprecated
*/
@Deprecated
public static final int foo=0x01010000;)EOF"));
public static final int foo=0x01010000;)EOF";
EXPECT_NE(std::string::npos, actual.find(expectedText));
}
TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {

View File

@@ -104,28 +104,34 @@ TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) {
std::string actual;
ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual));
EXPECT_NE(std::string::npos, actual.find(
const char* expectedAccessInternet =
R"EOF( /**
* Required to access the internet.
* Added in API 1.
*/
public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF"));
public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF";
EXPECT_NE(std::string::npos, actual.find(
EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet));
const char* expectedPlayOutside =
R"EOF( /**
* @deprecated This permission is for playing outside.
*/
@Deprecated
public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF"));
public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF";
EXPECT_NE(std::string::npos, actual.find(
EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside));
const char* expectedSecret =
R"EOF( /**
* This is a private permission for system only!
* @hide
* @SystemApi
*/
@android.annotation.SystemApi
public static final String SECRET="android.permission.SECRET";)EOF"));
public static final String SECRET="android.permission.SECRET";)EOF";
EXPECT_NE(std::string::npos, actual.find(expectedSecret));
}
} // namespace aapt

View File

@@ -388,6 +388,10 @@ private:
std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
const Source& source,
IDiagnostics* diag) {
// We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
// causes errors when qualifying it with android::
using namespace android;
std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
if (!pbTable.has_string_pool()) {
@@ -395,29 +399,29 @@ std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& p
return {};
}
android::ResStringPool valuePool;
android::status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
pbTable.string_pool().data().size());
if (result != android::NO_ERROR) {
ResStringPool valuePool;
status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
pbTable.string_pool().data().size());
if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid string pool");
return {};
}
android::ResStringPool sourcePool;
ResStringPool sourcePool;
if (pbTable.has_source_pool()) {
result = sourcePool.setTo(pbTable.source_pool().data().data(),
pbTable.source_pool().data().size());
if (result != android::NO_ERROR) {
if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid source pool");
return {};
}
}
android::ResStringPool symbolPool;
ResStringPool symbolPool;
if (pbTable.has_symbol_pool()) {
result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
pbTable.symbol_pool().data().size());
if (result != android::NO_ERROR) {
if (result != NO_ERROR) {
diag->error(DiagMessage(source) << "invalid symbol pool");
return {};
}

View File

@@ -18,6 +18,7 @@
#include "ResourceTable.h"
#include "split/TableSplitter.h"
#include <algorithm>
#include <map>
#include <set>
#include <unordered_map>

View File

@@ -26,7 +26,7 @@
#include <androidfw/ResourceTypes.h>
#include <androidfw/TypeWrappers.h>
#include <android-base/macros.h>
#include <algorithm>
#include <map>
#include <string>

View File

@@ -17,6 +17,7 @@
#include "util/Files.h"
#include "util/Util.h"
#include <algorithm>
#include <cerrno>
#include <cstdio>
#include <dirent.h>

View File

@@ -17,6 +17,8 @@
#ifndef AAPT_MAYBE_H
#define AAPT_MAYBE_H
#include "util/TypeTraits.h"
#include <cassert>
#include <type_traits>
#include <utility>
@@ -276,13 +278,15 @@ inline Maybe<T> make_nothing() {
}
/**
* Define the == operator between Maybe<T> and Maybe<U> if the operator T == U is defined.
* Otherwise this won't be defined and the compiler will yell at the callsite instead of inside
* Maybe.h.
* Define the == operator between Maybe<T> and Maybe<U> only if the operator T == U is defined.
* That way the compiler will show an error at the callsite when comparing two Maybe<> objects
* whose inner types can't be compared.
*/
template <typename T, typename U>
auto operator==(const Maybe<T>& a, const Maybe<U>& b)
-> decltype(std::declval<T> == std::declval<U>) {
typename std::enable_if<
has_eq_op<T, U>::value,
bool
>::type operator==(const Maybe<T>& a, const Maybe<U>& b) {
if (a && b) {
return a.value() == b.value();
} else if (!a && !b) {
@@ -295,8 +299,10 @@ auto operator==(const Maybe<T>& a, const Maybe<U>& b)
* Same as operator== but negated.
*/
template <typename T, typename U>
auto operator!=(const Maybe<T>& a, const Maybe<U>& b)
-> decltype(std::declval<T> == std::declval<U>) {
typename std::enable_if<
has_eq_op<T, U>::value,
bool
>::type operator!=(const Maybe<T>& a, const Maybe<U>& b) {
return !(a == b);
}

View File

@@ -228,20 +228,24 @@ static void copyAttributes(Element* el, android::ResXMLParser* parser) {
std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag,
const Source& source) {
// We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
// causes errors when qualifying it with android::
using namespace android;
std::unique_ptr<Node> root;
std::stack<Node*> nodeStack;
android::ResXMLTree tree;
if (tree.setTo(data, dataLen) != android::NO_ERROR) {
ResXMLTree tree;
if (tree.setTo(data, dataLen) != NO_ERROR) {
return {};
}
android::ResXMLParser::event_code_t code;
while ((code = tree.next()) != android::ResXMLParser::BAD_DOCUMENT &&
code != android::ResXMLParser::END_DOCUMENT) {
ResXMLParser::event_code_t code;
while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT &&
code != ResXMLParser::END_DOCUMENT) {
std::unique_ptr<Node> newNode;
switch (code) {
case android::ResXMLParser::START_NAMESPACE: {
case ResXMLParser::START_NAMESPACE: {
std::unique_ptr<Namespace> node = util::make_unique<Namespace>();
size_t len;
const char16_t* str16 = tree.getNamespacePrefix(&len);
@@ -257,7 +261,7 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break;
}
case android::ResXMLParser::START_TAG: {
case ResXMLParser::START_TAG: {
std::unique_ptr<Element> node = util::make_unique<Element>();
size_t len;
const char16_t* str16 = tree.getElementNamespace(&len);
@@ -276,7 +280,7 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break;
}
case android::ResXMLParser::TEXT: {
case ResXMLParser::TEXT: {
std::unique_ptr<Text> node = util::make_unique<Text>();
size_t len;
const char16_t* str16 = tree.getText(&len);
@@ -287,8 +291,8 @@ std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnost
break;
}
case android::ResXMLParser::END_NAMESPACE:
case android::ResXMLParser::END_TAG:
case ResXMLParser::END_NAMESPACE:
case ResXMLParser::END_TAG:
assert(!nodeStack.empty());
nodeStack.pop();
break;

View File

@@ -33,22 +33,22 @@ TEST(XmlUtilTest, ExtractPackageFromNamespace) {
xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res/a");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"a"), p.value().package);
EXPECT_EQ(false, p.value().privateNamespace);
EXPECT_FALSE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/android");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"android"), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace);
EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/prv/res/com.test");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(u"com.test"), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace);
EXPECT_TRUE(p.value().privateNamespace);
p = xml::extractPackageFromNamespace(u"http://schemas.android.com/apk/res-auto");
AAPT_ASSERT_TRUE(p);
EXPECT_EQ(std::u16string(), p.value().package);
EXPECT_EQ(true, p.value().privateNamespace);
EXPECT_TRUE(p.value().privateNamespace);
}
} // namespace aapt