mirror of
https://github.com/microsoft/vcpkg
synced 2024-11-20 16:06:00 -07:00
Android Support: Exporting to Android Archive (AAR) (#10271)
* added android triplets * added android support to vcpkg * added export directories to git ignore * fix libraries naming * added vckpg sources to visual studio project files * rename file location * issue with std::string fs:path copy initialization * format path on VStudio * fix checks format cannot work on fs::path * support header only libraries * support using architecture instead of triplets * added prefab support * added debug logs and prefab debug flag * added support for empty packages i.e openssl
This commit is contained in:
parent
6283a51112
commit
52b5dfd2ef
9 changed files with 972 additions and 9 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -304,6 +304,10 @@ __pycache__/
|
|||
!triplets/community/x86-windows-static.cmake
|
||||
!triplets/community/x86-windows-static-md.cmake
|
||||
!triplets/community/x64-osx-dynamic.cmake
|
||||
!triplets/community/x64-android.cmake
|
||||
!triplets/community/x86-android.cmake
|
||||
!triplets/community/arm-android.cmake
|
||||
!triplets/community/arm64-android.cmake
|
||||
!triplets/arm-uwp.cmake
|
||||
!triplets/x64-uwp.cmake
|
||||
!triplets/x64-windows.cmake
|
||||
|
@ -320,3 +324,5 @@ __pycache__/
|
|||
# vcpkg - End
|
||||
############################################################
|
||||
archives
|
||||
.DS_Store
|
||||
prefab/
|
124
docs/specifications/prefab.md
Normal file
124
docs/specifications/prefab.md
Normal file
|
@ -0,0 +1,124 @@
|
|||
## Exporting to Android Archives (AAR files)
|
||||
|
||||
Vcpkg current supports exporting to android archive files([AAR files](https://developer.android.com/studio/projects/android-library)). Once the archive is created it can imported in Android Studio as a native dependent. The archive is automatically consumed using [android studio's prefab tool](https://github.com/google/prefab). For more information on Prefab checkout the following article ["Native Dependencies in Android Studio 4.0"](https://android-developers.googleblog.com/2020/02/native-dependencies-in-android-studio-40.html) and the documentation on how to use prefab on [https://google.github.io/prefab/](https://google.github.io/prefab).
|
||||
|
||||
#### To support export to android the following tools should be available;
|
||||
|
||||
- `maven <optional>`
|
||||
- `ndk <required>`
|
||||
- `7zip <required on windows>` or `zip <required on linux>`
|
||||
|
||||
**Android triplets that support the following architectures arm64-v8a, armeabi-v7a, x86_64 x86 must be present**
|
||||
|
||||
#### An example of a triplet configuration targeting android would be
|
||||
|
||||
```cmake
|
||||
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE dynamic)
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME Android)
|
||||
```
|
||||
|
||||
The following table outlines the mapping from vcpkg architectures to android architectures
|
||||
|
||||
|vcpkg architecture | android architecture |
|
||||
|-------------------|----------------------|
|
||||
|arm64 | arm64-v8a |
|
||||
|arm | armeabi-v7a |
|
||||
|x64 | x86_64 |
|
||||
|x86 | x86 |
|
||||
|
||||
**Please note the four architectures are required. If any is missing the export will fail**
|
||||
**To export the following environment `ANDROID_NDK_HOME` variable is required for exporting**
|
||||
|
||||
#### Example exporting [jsoncpp]
|
||||
The `--prefab-maven` flag is option. Only call it when you have maven installed
|
||||
```
|
||||
./vcpkg export --triplet x64-android jsoncpp --prefab --prefab-maven
|
||||
```
|
||||
|
||||
```
|
||||
The following packages are already built and will be exported:
|
||||
jsoncpp:x86-android
|
||||
Exporting package jsoncpp...
|
||||
[INFO] Scanning for projects...
|
||||
[INFO]
|
||||
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
|
||||
[INFO] Building Maven Stub Project (No POM) 1
|
||||
[INFO] --------------------------------[ pom ]---------------------------------
|
||||
[INFO]
|
||||
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
|
||||
[INFO] Installing<root>/prefab/jsoncpp/jsoncpp-1.9.2.aar to /.m2/repository/com/vcpkg/ndk/support/jsoncpp/1.9.2/jsoncpp-1.9.2.aar
|
||||
[INFO] Installing <vcpkg_root>/prefab/jsoncpp/pom.xml to /.m2/repository/com/vcpkg/ndk/support/jsoncpp/1.9.2/jsoncpp-1.9.2.pom
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 0.301 s
|
||||
[INFO] Finished at: 2020-03-01T10:18:15Z
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
In app/build.gradle
|
||||
|
||||
com.vcpkg.ndk.support:jsoncpp:1.9.2
|
||||
|
||||
And cmake flags
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_shared'
|
||||
cppFlags "-std=c++17"
|
||||
}
|
||||
}
|
||||
|
||||
In gradle.properties
|
||||
|
||||
android.enablePrefab=true
|
||||
android.enableParallelJsonGen=false
|
||||
android.prefabVersion=${prefab.version}
|
||||
|
||||
Successfuly exported jsoncpp. Checkout <vcpkg_root>/prefab/jsoncpp/aar
|
||||
```
|
||||
|
||||
#### The output directory after export
|
||||
```
|
||||
prefab
|
||||
└── jsoncpp
|
||||
├── aar
|
||||
│ ├── AndroidManifest.xml
|
||||
│ ├── META-INF
|
||||
│ │ └── LICENCE
|
||||
│ └── prefab
|
||||
│ ├── modules
|
||||
│ │ └── jsoncpp
|
||||
│ │ ├── include
|
||||
│ │ │ └── json
|
||||
│ │ │ ├── allocator.h
|
||||
│ │ │ ├── assertions.h
|
||||
│ │ │ ├── autolink.h
|
||||
│ │ │ ├── config.h
|
||||
│ │ │ ├── forwards.h
|
||||
│ │ │ ├── json.h
|
||||
│ │ │ ├── json_features.h
|
||||
│ │ │ ├── reader.h
|
||||
│ │ │ ├── value.h
|
||||
│ │ │ ├── version.h
|
||||
│ │ │ └── writer.h
|
||||
│ │ ├── libs
|
||||
│ │ │ ├── android.arm64-v8a
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── libjsoncpp.so
|
||||
│ │ │ ├── android.armeabi-v7a
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── libjsoncpp.so
|
||||
│ │ │ ├── android.x86
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── libjsoncpp.so
|
||||
│ │ │ └── android.x86_64
|
||||
│ │ │ ├── abi.json
|
||||
│ │ │ └── libjsoncpp.so
|
||||
│ │ └── module.json
|
||||
│ └── prefab.json
|
||||
├── jsoncpp-1.9.2.aar
|
||||
└── pom.xml
|
||||
|
||||
13 directories, 25 files
|
||||
```
|
82
toolsrc/include/vcpkg/export.prefab.h
Normal file
82
toolsrc/include/vcpkg/export.prefab.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
#pragma once
|
||||
|
||||
#include <vcpkg/base/system.h>
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg::Export::Prefab
|
||||
{
|
||||
constexpr int kFragmentSize = 3;
|
||||
|
||||
struct Options
|
||||
{
|
||||
Optional<std::string> maybe_group_id;
|
||||
Optional<std::string> maybe_artifact_id;
|
||||
Optional<std::string> maybe_version;
|
||||
Optional<std::string> maybe_min_sdk;
|
||||
Optional<std::string> maybe_target_sdk;
|
||||
bool enable_maven;
|
||||
bool enable_debug;
|
||||
};
|
||||
struct NdkVersion
|
||||
{
|
||||
NdkVersion(int _major, int _minor, int _patch) : m_major{_major},
|
||||
m_minor{_minor},
|
||||
m_patch{_patch}{
|
||||
}
|
||||
int major() { return this->m_major; }
|
||||
int minor() { return this->m_minor; }
|
||||
int patch() { return this->m_patch; }
|
||||
std::string to_string();
|
||||
void to_string(std::string& out);
|
||||
|
||||
private:
|
||||
int m_major;
|
||||
int m_minor;
|
||||
int m_patch;
|
||||
};
|
||||
|
||||
struct ABIMetadata
|
||||
{
|
||||
std::string abi;
|
||||
int api;
|
||||
int ndk;
|
||||
std::string stl;
|
||||
std::string to_string();
|
||||
};
|
||||
|
||||
struct PlatformModuleMetadata
|
||||
{
|
||||
std::vector<std::string> export_libraries;
|
||||
std::string library_name;
|
||||
std::string to_json();
|
||||
};
|
||||
|
||||
struct ModuleMetadata
|
||||
{
|
||||
std::vector<std::string> export_libraries;
|
||||
std::string library_name;
|
||||
PlatformModuleMetadata android;
|
||||
std::string to_json();
|
||||
};
|
||||
|
||||
struct PackageMetadata
|
||||
{
|
||||
std::string name;
|
||||
int schema;
|
||||
std::vector<std::string> dependencies;
|
||||
std::string version;
|
||||
std::string to_json();
|
||||
};
|
||||
|
||||
|
||||
|
||||
void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& prefab_options, const Triplet& triplet);
|
||||
Optional<std::string> find_ndk_version(const std::string &content);
|
||||
Optional<NdkVersion> to_version(const std::string &version);
|
||||
}
|
|
@ -23,6 +23,11 @@ namespace vcpkg
|
|||
static const Triplet X64_UWP;
|
||||
static const Triplet ARM_UWP;
|
||||
static const Triplet ARM64_UWP;
|
||||
|
||||
static const Triplet ARM_ANDROID;
|
||||
static const Triplet ARM64_ANDROID;
|
||||
static const Triplet X86_ANDROID;
|
||||
static const Triplet X64_ANDROID;
|
||||
|
||||
const std::string& canonical_name() const;
|
||||
const std::string& to_string() const;
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace vcpkg
|
|||
namespace Tools
|
||||
{
|
||||
static const std::string SEVEN_ZIP = "7zip";
|
||||
static const std::string SEVEN_ZIP_ALT = "7z";
|
||||
static const std::string MAVEN = "mvn";
|
||||
static const std::string CMAKE = "cmake";
|
||||
static const std::string GIT = "git";
|
||||
static const std::string NINJA = "ninja";
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/export.chocolatey.h>
|
||||
#include <vcpkg/export.prefab.h>
|
||||
#include <vcpkg/export.h>
|
||||
#include <vcpkg/export.ifw.h>
|
||||
#include <vcpkg/help.h>
|
||||
|
@ -196,6 +197,7 @@ namespace vcpkg::Export
|
|||
{
|
||||
constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, "zip", "zip");
|
||||
constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, "7z", "7zip");
|
||||
constexpr const ArchiveFormat AAR(ArchiveFormat::BackingEnum::ZIP, "aar", "zip");
|
||||
}
|
||||
|
||||
static fs::path do_archive_export(const VcpkgPaths& paths,
|
||||
|
@ -263,6 +265,7 @@ namespace vcpkg::Export
|
|||
bool zip = false;
|
||||
bool seven_zip = false;
|
||||
bool chocolatey = false;
|
||||
bool prefab = false;
|
||||
bool all_installed = false;
|
||||
|
||||
Optional<std::string> maybe_output;
|
||||
|
@ -271,6 +274,7 @@ namespace vcpkg::Export
|
|||
Optional<std::string> maybe_nuget_version;
|
||||
|
||||
IFW::Options ifw_options;
|
||||
Prefab::Options prefab_options;
|
||||
Chocolatey::Options chocolatey_options;
|
||||
std::vector<PackageSpec> specs;
|
||||
};
|
||||
|
@ -293,8 +297,20 @@ namespace vcpkg::Export
|
|||
static constexpr StringLiteral OPTION_CHOCOLATEY_MAINTAINER = "--x-maintainer";
|
||||
static constexpr StringLiteral OPTION_CHOCOLATEY_VERSION_SUFFIX = "--x-version-suffix";
|
||||
static constexpr StringLiteral OPTION_ALL_INSTALLED = "--x-all-installed";
|
||||
|
||||
static constexpr StringLiteral OPTION_PREFAB = "--prefab";
|
||||
static constexpr StringLiteral OPTION_PREFAB_GROUP_ID = "--prefab-group-id";
|
||||
static constexpr StringLiteral OPTION_PREFAB_ARTIFACT_ID = "--prefab-artifact-id";
|
||||
static constexpr StringLiteral OPTION_PREFAB_VERSION = "--prefab-version";
|
||||
static constexpr StringLiteral OPTION_PREFAB_SDK_MIN_VERSION = "--prefab-min-sdk";
|
||||
static constexpr StringLiteral OPTION_PREFAB_SDK_TARGET_VERSION = "--prefab-target-sdk";
|
||||
static constexpr StringLiteral OPTION_PREFAB_ENABLE_MAVEN = "--prefab-maven";
|
||||
static constexpr StringLiteral OPTION_PREFAB_ENABLE_DEBUG = "--prefab-debug";
|
||||
|
||||
|
||||
static constexpr std::array<CommandSwitch, 8> EXPORT_SWITCHES = {{
|
||||
|
||||
|
||||
static constexpr std::array<CommandSwitch, 11> EXPORT_SWITCHES = {{
|
||||
{OPTION_DRY_RUN, "Do not actually export"},
|
||||
{OPTION_RAW, "Export to an uncompressed directory"},
|
||||
{OPTION_NUGET, "Export a NuGet package"},
|
||||
|
@ -302,10 +318,13 @@ namespace vcpkg::Export
|
|||
{OPTION_ZIP, "Export to a zip file"},
|
||||
{OPTION_SEVEN_ZIP, "Export to a 7zip (.7z) file"},
|
||||
{OPTION_CHOCOLATEY, "Export a Chocolatey package (experimental feature)"},
|
||||
{OPTION_PREFAB, "Export to Prefab format"},
|
||||
{OPTION_PREFAB_ENABLE_MAVEN, "Enable maven"},
|
||||
{OPTION_PREFAB_ENABLE_DEBUG, "Enable prefab debug"},
|
||||
{OPTION_ALL_INSTALLED, "Export all installed packages"},
|
||||
}};
|
||||
|
||||
static constexpr std::array<CommandSetting, 10> EXPORT_SETTINGS = {{
|
||||
static constexpr std::array<CommandSetting, 15> EXPORT_SETTINGS = {{
|
||||
{OPTION_OUTPUT, "Specify the output name (used to construct filename)"},
|
||||
{OPTION_NUGET_ID, "Specify the id for the exported NuGet package (overrides --output)"},
|
||||
{OPTION_NUGET_VERSION, "Specify the version for the exported NuGet package"},
|
||||
|
@ -318,6 +337,11 @@ namespace vcpkg::Export
|
|||
"Specify the maintainer for the exported Chocolatey package (experimental feature)"},
|
||||
{OPTION_CHOCOLATEY_VERSION_SUFFIX,
|
||||
"Specify the version suffix to add for the exported Chocolatey package (experimental feature)"},
|
||||
{OPTION_PREFAB_GROUP_ID, "GroupId uniquely identifies your project according maven specifications"},
|
||||
{OPTION_PREFAB_ARTIFACT_ID, "Artifact Id is the name of the project according maven specifications"},
|
||||
{OPTION_PREFAB_VERSION, "Version is the name of the project according maven specifications"},
|
||||
{OPTION_PREFAB_SDK_MIN_VERSION, "Android minimum supported sdk version"},
|
||||
{OPTION_PREFAB_SDK_TARGET_VERSION, "Android target sdk version"},
|
||||
}};
|
||||
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
|
@ -343,8 +367,11 @@ namespace vcpkg::Export
|
|||
ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend();
|
||||
ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend();
|
||||
ret.chocolatey = options.switches.find(OPTION_CHOCOLATEY) != options.switches.cend();
|
||||
ret.all_installed = options.switches.find(OPTION_ALL_INSTALLED) != options.switches.end();
|
||||
ret.prefab = options.switches.find(OPTION_PREFAB) != options.switches.cend();
|
||||
ret.prefab_options.enable_maven = options.switches.find(OPTION_PREFAB_ENABLE_MAVEN) != options.switches.cend();
|
||||
ret.prefab_options.enable_debug = options.switches.find(OPTION_PREFAB_ENABLE_DEBUG) != options.switches.cend();
|
||||
ret.maybe_output = maybe_lookup(options.settings, OPTION_OUTPUT);
|
||||
ret.all_installed = options.switches.find(OPTION_ALL_INSTALLED) != options.switches.end();
|
||||
|
||||
if (ret.all_installed)
|
||||
{
|
||||
|
@ -363,10 +390,10 @@ namespace vcpkg::Export
|
|||
});
|
||||
}
|
||||
|
||||
if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run && !ret.chocolatey)
|
||||
if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run && !ret.chocolatey && !ret.prefab)
|
||||
{
|
||||
System::print2(System::Color::error,
|
||||
"Must provide at least one export type: --raw --nuget --ifw --zip --7zip --chocolatey\n");
|
||||
"Must provide at least one export type: --raw --nuget --ifw --zip --7zip --chocolatey --prefab\n");
|
||||
System::print2(COMMAND_STRUCTURE.example_text);
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
@ -417,6 +444,16 @@ namespace vcpkg::Export
|
|||
{OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path},
|
||||
{OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path},
|
||||
});
|
||||
|
||||
options_implies(OPTION_PREFAB,
|
||||
ret.prefab,
|
||||
{
|
||||
{OPTION_PREFAB_ARTIFACT_ID, ret.prefab_options.maybe_artifact_id},
|
||||
{OPTION_PREFAB_GROUP_ID, ret.prefab_options.maybe_group_id},
|
||||
{OPTION_PREFAB_SDK_MIN_VERSION, ret.prefab_options.maybe_min_sdk},
|
||||
{OPTION_PREFAB_SDK_TARGET_VERSION, ret.prefab_options.maybe_target_sdk},
|
||||
{OPTION_PREFAB_VERSION, ret.prefab_options.maybe_version},
|
||||
});
|
||||
|
||||
options_implies(OPTION_CHOCOLATEY,
|
||||
ret.chocolatey,
|
||||
|
@ -605,6 +642,10 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
|
|||
Chocolatey::do_export(export_plan, paths, opts.chocolatey_options);
|
||||
}
|
||||
|
||||
if(opts.prefab){
|
||||
Prefab::do_export(export_plan, paths, opts.prefab_options, default_triplet);
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
|
695
toolsrc/src/vcpkg/export.prefab.cpp
Normal file
695
toolsrc/src/vcpkg/export.prefab.cpp
Normal file
|
@ -0,0 +1,695 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/checks.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/system.process.h>
|
||||
#include <vcpkg/build.h>
|
||||
#include <vcpkg/cmakevars.h>
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/export.h>
|
||||
#include <vcpkg/export.prefab.h>
|
||||
#include <vcpkg/install.h>
|
||||
|
||||
namespace vcpkg::Export::Prefab
|
||||
{
|
||||
using Dependencies::ExportPlanAction;
|
||||
using Dependencies::ExportPlanType;
|
||||
using Install::InstallDir;
|
||||
using System::CPUArchitecture;
|
||||
|
||||
|
||||
|
||||
std::vector<fs::path> find_modules(const VcpkgPaths& system, const fs::path& root, const std::string& ext)
|
||||
{
|
||||
std::vector<fs::path> paths;
|
||||
Files::Filesystem& utils = system.get_filesystem();
|
||||
std::error_code error_code;
|
||||
if (!utils.exists(root, error_code) || !utils.is_directory(root)) return paths;
|
||||
|
||||
fs::stdfs::recursive_directory_iterator it(root);
|
||||
fs::stdfs::recursive_directory_iterator endit;
|
||||
|
||||
while (it != endit)
|
||||
{
|
||||
if (utils.is_regular_file(*it) && it->path().extension() == ext)
|
||||
{
|
||||
paths.push_back(it->path().filename());
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
std::string NdkVersion::to_string()
|
||||
{
|
||||
std::string ret;
|
||||
this->to_string(ret);
|
||||
return ret;
|
||||
}
|
||||
void NdkVersion::to_string(std::string& out)
|
||||
{
|
||||
out.append("NdkVersion{major=")
|
||||
.append(std::to_string(major()))
|
||||
.append(",minor=")
|
||||
.append(std::to_string(minor()))
|
||||
.append(",patch=")
|
||||
.append(std::to_string(patch()))
|
||||
.append("}");
|
||||
}
|
||||
|
||||
std::string jsonify(const std::vector<std::string>& dependencies)
|
||||
{
|
||||
std::vector<std::string> deps;
|
||||
for (const auto& dep : dependencies)
|
||||
{
|
||||
deps.push_back("\"" + dep + "\"");
|
||||
}
|
||||
return Strings::join(",", deps);
|
||||
}
|
||||
|
||||
std::string null_if_empty(const std::string& str)
|
||||
{
|
||||
std::string copy = str;
|
||||
if (copy.size() == 0)
|
||||
{
|
||||
copy = "null";
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = "\"" + copy + "\"";
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::string null_if_empty_array(const std::string& str)
|
||||
{
|
||||
std::string copy = str;
|
||||
if (copy.size() == 0)
|
||||
{
|
||||
copy = "null";
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = "[" + copy + "]";
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::string ABIMetadata::to_string()
|
||||
{
|
||||
std::string TEMPLATE = R"({
|
||||
"abi":"@ABI@",
|
||||
"api":@API@,
|
||||
"ndk":@NDK@,
|
||||
"stl":"@STL@"
|
||||
})";
|
||||
std::string json = Strings::replace_all(std::move(TEMPLATE), "@ABI@", abi);
|
||||
json = Strings::replace_all(std::move(json), "@API@", std::to_string(api));
|
||||
json = Strings::replace_all(std::move(json), "@NDK@", std::to_string(ndk));
|
||||
json = Strings::replace_all(std::move(json), "@STL@", stl);
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string PlatformModuleMetadata::to_json()
|
||||
{
|
||||
std::string TEMPLATE = R"({
|
||||
"export_libraries": @LIBRARIES@,
|
||||
"library_name": @LIBRARY_NAME@
|
||||
})";
|
||||
|
||||
std::string json = Strings::replace_all(std::move(TEMPLATE), "@LIBRARY_NAME@", null_if_empty(library_name));
|
||||
json = Strings::replace_all(std::move(json), "@LIBRARIES@", null_if_empty_array(jsonify(export_libraries)));
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string ModuleMetadata::to_json()
|
||||
{
|
||||
std::string TEMPLATE = R"({
|
||||
"export_libraries": [@LIBRARIES@],
|
||||
"library_name":@LIBRARY_NAME@,
|
||||
"android": @ANDROID_METADATA@
|
||||
})";
|
||||
|
||||
std::string json = Strings::replace_all(std::move(TEMPLATE), "@LIBRARY_NAME@", null_if_empty(library_name));
|
||||
json = Strings::replace_all(std::move(json), "@LIBRARIES@", jsonify(export_libraries));
|
||||
json = Strings::replace_all(std::move(json), "@ANDROID_METADATA@", android.to_json());
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string PackageMetadata::to_json()
|
||||
{
|
||||
std::string deps = jsonify(dependencies);
|
||||
|
||||
std::string TEMPLATE = R"({
|
||||
"name":"@PACKAGE_NAME@",
|
||||
"schema_version": @PACKAGE_SCHEMA@,
|
||||
"dependencies":[@PACKAGE_DEPS@],
|
||||
"version":"@PACKAGE_VERSION@"
|
||||
})";
|
||||
std::string json = Strings::replace_all(std::move(TEMPLATE), "@PACKAGE_NAME@", name);
|
||||
json = Strings::replace_all(std::move(json), "@PACKAGE_SCHEMA@", std::to_string(schema));
|
||||
json = Strings::replace_all(std::move(json), "@PACKAGE_DEPS@", deps);
|
||||
json = Strings::replace_all(std::move(json), "@PACKAGE_VERSION@", version);
|
||||
return json;
|
||||
}
|
||||
|
||||
Optional<std::string> find_ndk_version(const std::string& content)
|
||||
{
|
||||
std::smatch pkg_match;
|
||||
std::regex pkg_regex(R"(Pkg\.Revision\s*=\s*(\d+)(\.\d+)(\.\d+)\s*)");
|
||||
|
||||
if (std::regex_search(content, pkg_match, pkg_regex))
|
||||
{
|
||||
for (const auto& p : pkg_match)
|
||||
{
|
||||
std::string delimiter = "=";
|
||||
std::string s = p.str();
|
||||
auto it = s.find(delimiter);
|
||||
if (it != std::string::npos)
|
||||
{
|
||||
std::string token = (s.substr(s.find(delimiter) + 1, s.size()));
|
||||
return Strings::trim(std::move(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<NdkVersion> to_version(const std::string& version)
|
||||
{
|
||||
if (version.size() > 100) return {};
|
||||
size_t last = 0;
|
||||
size_t next = 0;
|
||||
std::vector<int> fragments(0);
|
||||
|
||||
while ((next = version.find(".", last)) != std::string::npos)
|
||||
{
|
||||
fragments.push_back(std::stoi(version.substr(last, next - last)));
|
||||
last = next + 1;
|
||||
}
|
||||
fragments.push_back(std::stoi(version.substr(last)));
|
||||
if (fragments.size() == kFragmentSize)
|
||||
{
|
||||
return NdkVersion(fragments[0], fragments[1], fragments[2]);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static void compress_directory(const VcpkgPaths& paths, const fs::path& source, const fs::path& destination)
|
||||
{
|
||||
auto& fs = paths.get_filesystem();
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
fs.remove(destination, ec);
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, !fs.exists(destination), "Could not remove file: %s", destination.u8string());
|
||||
#if defined(_WIN32)
|
||||
auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP);
|
||||
|
||||
System::cmd_execute_and_capture_output(
|
||||
Strings::format(
|
||||
R"("%s" a "%s" "%s\*")", seven_zip_exe.u8string(), destination.u8string(), source.u8string()),
|
||||
System::get_clean_environment());
|
||||
#else
|
||||
System::cmd_execute_clean(
|
||||
Strings::format(R"(cd '%s' && zip --quiet -r '%s' *)", source.u8string(), destination.u8string()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void maven_install(const fs::path& aar, const fs::path& pom, const Options& prefab_options)
|
||||
{
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2("\n[DEBUG] Installing POM and AAR file to ~/.m2\n\n");
|
||||
}
|
||||
const char* cmd_line_format = prefab_options.enable_debug ? R"("%s" "install:install-file" "-Dfile=%s" "-DpomFile=%s")"
|
||||
: R"("%s" "-q" "install:install-file" "-Dfile=%s" "-DpomFile=%s")";
|
||||
|
||||
const auto cmd_line = Strings::format(cmd_line_format,
|
||||
Tools::MAVEN,
|
||||
aar.u8string(),
|
||||
pom.u8string());
|
||||
const int exit_code = System::cmd_execute_clean(cmd_line);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: %s installing maven file", aar.generic_u8string());
|
||||
}
|
||||
|
||||
Build::PreBuildInfo build_info_from_triplet(const VcpkgPaths& paths,
|
||||
const std::unique_ptr<CMakeVars::CMakeVarProvider>& provider,
|
||||
const Triplet& triplet)
|
||||
{
|
||||
provider->load_generic_triplet_vars(triplet);
|
||||
const Build::PreBuildInfo pre_build_info(
|
||||
paths, triplet, provider->get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO));
|
||||
return pre_build_info;
|
||||
}
|
||||
|
||||
bool is_supported(const Build::PreBuildInfo& info)
|
||||
{
|
||||
return Strings::case_insensitive_ascii_equals(info.cmake_system_name, "android");
|
||||
}
|
||||
|
||||
void do_export(const std::vector<ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& prefab_options,
|
||||
const Triplet& default_triplet)
|
||||
{
|
||||
auto provider = CMakeVars::make_triplet_cmake_var_provider(paths);
|
||||
|
||||
auto build_info = build_info_from_triplet(paths, provider, default_triplet);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, is_supported(build_info), "Currenty supported on android triplets");
|
||||
|
||||
std::vector<VcpkgPaths::TripletFile> available_triplets = paths.get_available_triplets();
|
||||
|
||||
std::unordered_map<CPUArchitecture, std::string> required_archs = {
|
||||
{CPUArchitecture::ARM, "armeabi-v7a"},
|
||||
{CPUArchitecture::ARM64, "arm64-v8a"},
|
||||
{CPUArchitecture::X86, "x86"},
|
||||
{CPUArchitecture::X64, "x86_64"}};
|
||||
|
||||
std::unordered_map<CPUArchitecture, int> cpu_architecture_api_map = {{CPUArchitecture::ARM64, 21},
|
||||
{CPUArchitecture::ARM, 16},
|
||||
{CPUArchitecture::X64, 21},
|
||||
{CPUArchitecture::X86, 16}};
|
||||
|
||||
|
||||
std::vector<Triplet> triplets;
|
||||
std::unordered_map<Triplet, std::string> triplet_abi_map;
|
||||
std::unordered_map<Triplet, int> triplet_api_map;
|
||||
|
||||
for (auto& triplet_file : available_triplets){
|
||||
if (triplet_file.name.size() > 0){
|
||||
Triplet triplet = Triplet::from_canonical_name(std::move(triplet_file.name));
|
||||
auto build_info = build_info_from_triplet(paths, provider, triplet);
|
||||
if (is_supported(build_info)){
|
||||
auto cpu_architecture =System::to_cpu_architecture(build_info.target_architecture).value_or_exit(VCPKG_LINE_INFO);
|
||||
auto required_arch = required_archs.find(cpu_architecture);
|
||||
if (required_arch != required_archs.end()){
|
||||
triplets.push_back(triplet);
|
||||
triplet_abi_map[triplet] = required_archs[cpu_architecture];
|
||||
triplet_api_map[triplet] = cpu_architecture_api_map[cpu_architecture];
|
||||
required_archs.erase(required_arch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, required_archs.empty(), "Export requires the following architectures arm64-v8a, armeabi-v7a, x86_64, x86 to be present");
|
||||
|
||||
Optional<std::string> android_ndk_home = System::get_environment_variable("ANDROID_NDK_HOME");
|
||||
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, android_ndk_home.has_value(), "Error: ANDROID_NDK_HOME environment missing");
|
||||
|
||||
Files::Filesystem& utils = paths.get_filesystem();
|
||||
|
||||
const fs::path ndk_location = android_ndk_home.value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
utils.exists(ndk_location),
|
||||
"Error: ANDROID_NDK_HOME Directory does not exists %s",
|
||||
ndk_location.generic_u8string());
|
||||
const fs::path source_properties_location = ndk_location / "source.properties";
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
utils.exists(ndk_location),
|
||||
"Error: source.properties missing in ANDROID_NDK_HOME directory %s",
|
||||
source_properties_location.generic_u8string());
|
||||
|
||||
std::string content = utils.read_contents(source_properties_location, VCPKG_LINE_INFO);
|
||||
|
||||
Optional<std::string> version_opt = find_ndk_version(content);
|
||||
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
version_opt.has_value(),
|
||||
"Error: NDK version missing %s",
|
||||
source_properties_location.generic_u8string());
|
||||
|
||||
NdkVersion version = to_version(version_opt.value_or_exit(VCPKG_LINE_INFO)).value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
const fs::path vcpkg_root_path = paths.root;
|
||||
const fs::path raw_exported_dir_path = vcpkg_root_path / "prefab";
|
||||
|
||||
utils.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
|
||||
|
||||
/*
|
||||
prefab
|
||||
└── <name>
|
||||
├── aar
|
||||
│ ├── AndroidManifest.xml
|
||||
│ ├── META-INF
|
||||
│ │ └── LICENCE
|
||||
│ └── prefab
|
||||
│ ├── modules
|
||||
│ │ └── <module>
|
||||
│ │ ├── include
|
||||
│ │ ├── libs
|
||||
│ │ │ ├── android.arm64-v8a
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── lib<module>.so
|
||||
│ │ │ ├── android.armeabi-v7a
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── lib<module>.so
|
||||
│ │ │ ├── android.x86
|
||||
│ │ │ │ ├── abi.json
|
||||
│ │ │ │ └── lib<module>.so
|
||||
│ │ │ └── android.x86_64
|
||||
│ │ │ ├── abi.json
|
||||
│ │ │ └── lib<module>.so
|
||||
│ │ └── module.json
|
||||
│ └── prefab.json
|
||||
├── <name>-<version>.aar
|
||||
└── pom.xml
|
||||
*/
|
||||
|
||||
std::unordered_map<std::string, std::string> version_map;
|
||||
|
||||
std::error_code error_code;
|
||||
|
||||
std::unordered_map<std::string, std::set<PackageSpec>> empty_package_dependencies;
|
||||
|
||||
//
|
||||
|
||||
for (const auto& action : export_plan)
|
||||
{
|
||||
|
||||
const std::string name = action.spec.name();
|
||||
auto dependencies = action.dependencies(default_triplet);
|
||||
|
||||
const auto build_info = Build::read_build_info(utils, paths.build_info_file_path(action.spec));
|
||||
const bool is_empty_package = build_info.policies.is_enabled(Build::BuildPolicy::EMPTY_PACKAGE);
|
||||
|
||||
|
||||
if(is_empty_package){
|
||||
empty_package_dependencies[name] = std::set<PackageSpec>();
|
||||
for(auto dependency : dependencies){
|
||||
if(empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end()){
|
||||
auto& child_deps = empty_package_dependencies[name];
|
||||
auto& parent_deps = empty_package_dependencies[dependency.name()];
|
||||
for(auto parent_dep: parent_deps){
|
||||
child_deps.insert(parent_dep);
|
||||
}
|
||||
}
|
||||
else {
|
||||
empty_package_dependencies[name].insert(dependency);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const fs::path per_package_dir_path = raw_exported_dir_path / name;
|
||||
|
||||
const auto& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
|
||||
const std::string norm_version = binary_paragraph.version;
|
||||
|
||||
version_map[name] = norm_version;
|
||||
|
||||
System::print2("\nExporting package ", name, "...\n");
|
||||
|
||||
fs::path package_directory = per_package_dir_path / "aar";
|
||||
fs::path prefab_directory = package_directory / "prefab";
|
||||
fs::path modules_directory = prefab_directory / "modules";
|
||||
|
||||
utils.create_directories(modules_directory, error_code);
|
||||
|
||||
std::string artifact_id = prefab_options.maybe_artifact_id.value_or(name);
|
||||
std::string group_id = prefab_options.maybe_group_id.value_or("com.vcpkg.ndk.support");
|
||||
std::string sdk_min_version = prefab_options.maybe_min_sdk.value_or("16");
|
||||
std::string sdk_target_version = prefab_options.maybe_target_sdk.value_or("29");
|
||||
|
||||
std::string MANIFEST_TEMPLATE =
|
||||
R"(<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="@GROUP_ID@.@ARTIFACT_ID@" android:versionCode="1" android:versionName="1.0">
|
||||
<uses-sdk android:minSdkVersion="@MIN_SDK_VERSION@" android:targetSdkVersion="@SDK_TARGET_VERSION@" />
|
||||
</manifest>)";
|
||||
std::string manifest = Strings::replace_all(std::move(MANIFEST_TEMPLATE), "@GROUP_ID@", group_id);
|
||||
manifest = Strings::replace_all(std::move(manifest), "@ARTIFACT_ID@", artifact_id);
|
||||
manifest = Strings::replace_all(std::move(manifest), "@MIN_SDK_VERSION@", sdk_min_version);
|
||||
manifest = Strings::replace_all(std::move(manifest), "@SDK_TARGET_VERSION@", sdk_target_version);
|
||||
|
||||
fs::path manifest_path = package_directory / "AndroidManifest.xml";
|
||||
fs::path prefab_path = prefab_directory / "prefab.json";
|
||||
|
||||
fs::path meta_dir = package_directory / "META-INF";
|
||||
|
||||
utils.create_directories(meta_dir, error_code);
|
||||
|
||||
const fs::path share_root =
|
||||
vcpkg_root_path / "packages" / Strings::format("%s_%s", name, action.spec.triplet());
|
||||
|
||||
utils.copy_file(share_root / "share" / name / "copyright",
|
||||
meta_dir / "LICENSE",
|
||||
fs::copy_options::overwrite_existing,
|
||||
error_code);
|
||||
|
||||
PackageMetadata pm;
|
||||
pm.name = artifact_id;
|
||||
pm.schema = 1;
|
||||
pm.version = norm_version;
|
||||
|
||||
std::set<PackageSpec> dependencies_minus_empty_packages;
|
||||
|
||||
for(auto dependency: dependencies){
|
||||
if(empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end()){
|
||||
for(auto& empty_package_dep: empty_package_dependencies[dependency.name()]){
|
||||
dependencies_minus_empty_packages.insert(empty_package_dep);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dependencies_minus_empty_packages.insert(dependency);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> pom_dependencies;
|
||||
|
||||
if (dependencies_minus_empty_packages.size() > 0)
|
||||
{
|
||||
pom_dependencies.push_back("\n<dependencies>");
|
||||
}
|
||||
|
||||
for (const auto& it : dependencies_minus_empty_packages)
|
||||
{
|
||||
std::string maven_pom = R"( <dependency>
|
||||
<groupId>@GROUP_ID@</groupId>
|
||||
<artifactId>@ARTIFACT_ID@</artifactId>
|
||||
<version>@VERSION@</version>
|
||||
<type>aar</type>
|
||||
<scope>runtime</scope>
|
||||
</dependency>)";
|
||||
std::string pom = Strings::replace_all(std::move(maven_pom), "@GROUP_ID@", group_id);
|
||||
pom = Strings::replace_all(std::move(pom), "@ARTIFACT_ID@", it.name());
|
||||
pom = Strings::replace_all(std::move(pom), "@VERSION@", version_map[it.name()]);
|
||||
pom_dependencies.push_back(pom);
|
||||
pm.dependencies.push_back(it.name());
|
||||
}
|
||||
|
||||
if (dependencies_minus_empty_packages.size() > 0)
|
||||
{
|
||||
pom_dependencies.push_back("</dependencies>\n");
|
||||
}
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format(
|
||||
"[DEBUG]\n\tWriting manifest\n\tTo %s\n\tWriting prefab meta data\n\tTo %s\n\n",
|
||||
manifest_path.generic_u8string(), prefab_path.generic_u8string()));
|
||||
}
|
||||
|
||||
utils.write_contents(manifest_path, manifest, VCPKG_LINE_INFO);
|
||||
utils.write_contents(prefab_path, pm.to_json(), VCPKG_LINE_INFO);
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
std::vector<std::string> triplet_names;
|
||||
for(auto triplet: triplets){
|
||||
triplet_names.push_back(triplet.canonical_name());
|
||||
}
|
||||
System::print2(Strings::format("[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(),
|
||||
Strings::join("\n\t", triplet_names)));
|
||||
}
|
||||
|
||||
for (const auto& triplet : triplets)
|
||||
{
|
||||
const fs::path listfile = vcpkg_root_path / "installed" / "vcpkg" / "info" /
|
||||
(Strings::format("%s_%s_%s", name, norm_version, triplet) + ".list");
|
||||
const fs::path installed_dir = vcpkg_root_path / "packages" / Strings::format("%s_%s", name, triplet);
|
||||
Checks::check_exit(VCPKG_LINE_INFO,
|
||||
utils.exists(listfile),
|
||||
"Error: Packages not installed %s:%s %s",
|
||||
name,
|
||||
triplet,
|
||||
listfile.generic_u8string());
|
||||
|
||||
fs::path libs = installed_dir / "lib";
|
||||
|
||||
std::vector<fs::path> modules;
|
||||
|
||||
std::vector<fs::path> modules_shared = find_modules(paths, libs, ".so");
|
||||
|
||||
for (const auto& module : modules_shared)
|
||||
{
|
||||
modules.push_back(module);
|
||||
}
|
||||
|
||||
std::vector<fs::path> modules_static = find_modules(paths, libs, ".a");
|
||||
for (const auto& module : modules_static)
|
||||
{
|
||||
modules.push_back(module);
|
||||
}
|
||||
|
||||
// header only libs
|
||||
if (modules.empty())
|
||||
{
|
||||
fs::path module_dir = modules_directory / name;
|
||||
fs::path module_libs_dir = module_dir / "libs";
|
||||
utils.create_directories(module_libs_dir, error_code);
|
||||
fs::path installed_headers_dir = installed_dir / "include";
|
||||
fs::path exported_headers_dir = module_dir / "include";
|
||||
|
||||
ModuleMetadata meta;
|
||||
fs::path module_meta_path = module_dir / "module.json";
|
||||
utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO);
|
||||
|
||||
utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& module : modules)
|
||||
{
|
||||
std::string module_name = module.stem().generic_u8string();
|
||||
std::string extension = module.extension().generic_u8string();
|
||||
|
||||
ABIMetadata ab;
|
||||
ab.abi = triplet_abi_map[triplet];
|
||||
ab.api = triplet_api_map[triplet];
|
||||
|
||||
ab.stl = Strings::contains(extension, "a") ?"c++_static": "c++_shared";
|
||||
ab.ndk = version.major();
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("[DEBUG] Found module %s:%s\n", module_name, ab.abi));
|
||||
}
|
||||
|
||||
module_name = Strings::trim(std::move(module_name));
|
||||
|
||||
if (Strings::starts_with(module_name, "lib"))
|
||||
{
|
||||
module_name = module_name.substr(3);
|
||||
}
|
||||
fs::path module_dir = (modules_directory / module_name);
|
||||
fs::path module_libs_dir =
|
||||
module_dir / "libs" / Strings::format("android.%s", ab.abi);
|
||||
utils.create_directories(module_libs_dir, error_code);
|
||||
|
||||
fs::path abi_path = module_libs_dir / "abi.json";
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("\tWriting abi metadata\n\tTo %s\n",
|
||||
abi_path.generic_u8string()));
|
||||
}
|
||||
utils.write_contents(abi_path, ab.to_string(), VCPKG_LINE_INFO);
|
||||
|
||||
fs::path installed_module_path = libs / module.filename();
|
||||
fs::path exported_module_path = module_libs_dir / module.filename();
|
||||
|
||||
utils.copy_file(installed_module_path,
|
||||
exported_module_path,
|
||||
fs::copy_options::overwrite_existing,
|
||||
error_code);
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("\tCopying libs\n\tFrom %s\n\tTo %s\n",
|
||||
installed_module_path.generic_u8string(), exported_module_path.generic_u8string()));
|
||||
}
|
||||
fs::path installed_headers_dir = installed_dir / "include";
|
||||
fs::path exported_headers_dir = module_libs_dir / "include";
|
||||
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("\tCopying headers\n\tFrom %s\n\tTo %s\n",
|
||||
installed_headers_dir.generic_u8string(), exported_headers_dir.generic_u8string()));
|
||||
}
|
||||
|
||||
utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive);
|
||||
|
||||
ModuleMetadata meta;
|
||||
|
||||
fs::path module_meta_path = module_dir / "module.json";
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("\tWriting module metadata\n\tTo %s\n\n",
|
||||
module_meta_path.generic_u8string()));
|
||||
}
|
||||
|
||||
utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs::path exported_archive_path = per_package_dir_path / Strings::format("%s-%s.aar", name, norm_version);
|
||||
fs::path pom_path = per_package_dir_path / "pom.xml";
|
||||
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(Strings::format("[DEBUG] Exporting AAR And POM\n\tAAR Path %s\n\tPOM Path %s\n",
|
||||
exported_archive_path.generic_u8string(), pom_path.generic_u8string()));
|
||||
}
|
||||
|
||||
compress_directory(paths, package_directory, exported_archive_path);
|
||||
|
||||
std::string POM = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<groupId>@GROUP_ID@</groupId>
|
||||
<artifactId>@ARTIFACT_ID@</artifactId>
|
||||
<version>@VERSION@</version>
|
||||
<packaging>aar</packaging>
|
||||
<description>The Vcpkg AAR for @ARTIFACT_ID@</description>
|
||||
<url>https://github.com/microsoft/vcpkg.git</url>
|
||||
@DEPENDENCIES@
|
||||
</project>)";
|
||||
|
||||
std::string pom = Strings::replace_all(std::move(POM), "@GROUP_ID@", group_id);
|
||||
pom = Strings::replace_all(std::move(pom), "@ARTIFACT_ID@", artifact_id);
|
||||
pom = Strings::replace_all(std::move(pom), "@DEPENDENCIES@", Strings::join("\n", pom_dependencies));
|
||||
pom = Strings::replace_all(std::move(pom), "@VERSION@", norm_version);
|
||||
|
||||
utils.write_contents(pom_path, pom, VCPKG_LINE_INFO);
|
||||
|
||||
if (prefab_options.enable_maven)
|
||||
{
|
||||
|
||||
maven_install(exported_archive_path, pom_path, prefab_options);
|
||||
if(prefab_options.enable_debug){
|
||||
System::print2(
|
||||
Strings::format("\n\n[DEBUG] Configuration properties in Android Studio\nIn app/build.gradle\n\n\t%s:%s:%s\n\n",
|
||||
group_id, artifact_id, norm_version));
|
||||
|
||||
System::print2(R"(And cmake flags
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_shared'
|
||||
cppFlags "-std=c++17"
|
||||
}
|
||||
}
|
||||
|
||||
)");
|
||||
|
||||
System::print2(R"(In gradle.properties
|
||||
|
||||
android.enablePrefab=true
|
||||
android.enableParallelJsonGen=false
|
||||
android.prefabVersion=${prefab.version}
|
||||
|
||||
)");}
|
||||
}
|
||||
System::print2(System::Color::success,
|
||||
Strings::format("Successfuly exported %s. Checkout %s \n",
|
||||
name,
|
||||
raw_exported_dir_path.generic_u8string()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,12 @@ namespace vcpkg
|
|||
const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp");
|
||||
const Triplet Triplet::ARM64_UWP = from_canonical_name("arm64-uwp");
|
||||
|
||||
//
|
||||
const Triplet Triplet::ARM_ANDROID = from_canonical_name("arm-android");
|
||||
const Triplet Triplet::ARM64_ANDROID = from_canonical_name("arm64-android");
|
||||
const Triplet Triplet::X86_ANDROID = from_canonical_name("x86-android");
|
||||
const Triplet Triplet::X64_ANDROID = from_canonical_name("x64-android");
|
||||
|
||||
Triplet Triplet::from_canonical_name(std::string&& triplet_as_string)
|
||||
{
|
||||
std::string s(Strings::ascii_to_lowercase(std::move(triplet_as_string)));
|
||||
|
@ -55,19 +61,19 @@ namespace vcpkg
|
|||
Optional<System::CPUArchitecture> Triplet::guess_architecture() const noexcept
|
||||
{
|
||||
using System::CPUArchitecture;
|
||||
if (*this == X86_WINDOWS || *this == X86_UWP)
|
||||
if (*this == X86_WINDOWS || *this == X86_UWP || *this == X86_ANDROID)
|
||||
{
|
||||
return CPUArchitecture::X86;
|
||||
}
|
||||
else if (*this == X64_WINDOWS || *this == X64_UWP)
|
||||
else if (*this == X64_WINDOWS || *this == X64_UWP || *this ==X64_ANDROID)
|
||||
{
|
||||
return CPUArchitecture::X64;
|
||||
}
|
||||
else if (*this == ARM_WINDOWS || *this == ARM_UWP)
|
||||
else if (*this == ARM_WINDOWS || *this == ARM_UWP || *this == ARM_ANDROID)
|
||||
{
|
||||
return CPUArchitecture::ARM;
|
||||
}
|
||||
else if (*this == ARM64_WINDOWS || *this == ARM64_UWP)
|
||||
else if (*this == ARM64_WINDOWS || *this == ARM64_UWP || *this == ARM64_ANDROID)
|
||||
{
|
||||
return CPUArchitecture::ARM64;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<ClInclude Include="..\include\vcpkg\export.chocolatey.h" />
|
||||
<ClInclude Include="..\include\vcpkg\export.h" />
|
||||
<ClInclude Include="..\include\vcpkg\export.ifw.h" />
|
||||
<ClInclude Include="..\include\vcpkg\export.prefab.h" />
|
||||
<ClInclude Include="..\include\vcpkg\globalstate.h" />
|
||||
<ClInclude Include="..\include\vcpkg\help.h" />
|
||||
<ClInclude Include="..\include\vcpkg\input.h" />
|
||||
|
@ -258,6 +259,7 @@
|
|||
<ClCompile Include="..\src\vcpkg\dependencies.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\export.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\export.chocolatey.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\export.prefab.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\globalstate.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\help.cpp" />
|
||||
<ClCompile Include="..\src\vcpkg\input.cpp" />
|
||||
|
|
Loading…
Reference in a new issue