Merge topic 'add_androidmk_generator'
42ce9f1e
Add support for creating prebuilt Android.mk filesd5257063
Export: Virtualize file generation step helpersf81b9475
Export: Factor out file generation steps into helpers
This commit is contained in:
commit
b93623550d
|
@ -55,3 +55,18 @@ build tree. In some cases, for example for packaging and for system
|
|||
wide installations, it is not desirable to write the user package
|
||||
registry. If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
|
||||
is enabled, the ``export(PACKAGE)`` command will do nothing.
|
||||
|
||||
::
|
||||
|
||||
export(TARGETS [target1 [target2 [...]]] [ANDROID_MK <filename>])
|
||||
|
||||
This signature exports cmake built targets to the android ndk build system
|
||||
by creating an Android.mk file that references the prebuilt targets. The
|
||||
Android NDK supports the use of prebuilt libraries, both static and shared.
|
||||
This allows cmake to build the libraries of a project and make them available
|
||||
to an ndk build system complete with transitive dependencies, include flags
|
||||
and defines required to use the libraries. The signature takes a list of
|
||||
targets and puts them in the Android.mk file specified by the ``<filename>``
|
||||
given. This signature can only be used if policy CMP0022 is NEW for all
|
||||
targets given. A error will be issued if that policy is set to OLD for one
|
||||
of the targets.
|
||||
|
|
|
@ -314,7 +314,8 @@ Installing Exports
|
|||
::
|
||||
|
||||
install(EXPORT <export-name> DESTINATION <dir>
|
||||
[NAMESPACE <namespace>] [FILE <name>.cmake]
|
||||
[NAMESPACE <namespace>] [[FILE <name>.cmake]|
|
||||
[EXPORT_ANDROID_MK <name>.mk]]
|
||||
[PERMISSIONS permissions...]
|
||||
[CONFIGURATIONS [Debug|Release|...]]
|
||||
[EXPORT_LINK_INTERFACE_LIBRARIES]
|
||||
|
@ -342,6 +343,13 @@ specified that does not match that given to the targets associated with
|
|||
included in the export but a target to which it links is not included
|
||||
the behavior is unspecified.
|
||||
|
||||
In additon to cmake language files, the ``EXPORT_ANDROID_MK`` option maybe
|
||||
used to specifiy an export to the android ndk build system. The Android
|
||||
NDK supports the use of prebuilt libraries, both static and shared. This
|
||||
allows cmake to build the libraries of a project and make them available
|
||||
to an ndk build system complete with transitive dependencies, include flags
|
||||
and defines required to use the libraries.
|
||||
|
||||
The ``EXPORT`` form is useful to help outside projects use targets built
|
||||
and installed by the current project. For example, the code
|
||||
|
||||
|
@ -349,9 +357,11 @@ and installed by the current project. For example, the code
|
|||
|
||||
install(TARGETS myexe EXPORT myproj DESTINATION bin)
|
||||
install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
|
||||
install(EXPORT_ANDROID_MK myexp DESTINATION share/ndk-modules)
|
||||
|
||||
will install the executable myexe to ``<prefix>/bin`` and code to import
|
||||
it in the file ``<prefix>/lib/myproj/myproj.cmake``. An outside project
|
||||
it in the file ``<prefix>/lib/myproj/myproj.cmake`` and
|
||||
``<prefix>/lib/share/ndk-modules/Android.mk``. An outside project
|
||||
may load this file with the include command and reference the ``myexe``
|
||||
executable from the installation tree using the imported target name
|
||||
``mp_myexe`` as if the target were built in its own tree.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
add_androidmk_generator
|
||||
-----------------------
|
||||
|
||||
* The :command:`install` command gained an ``EXPORT_ANDROID_MK``
|
||||
subcommand to install ``Android.mk`` files referencing installed
|
||||
libraries as prebuilts for the Android NDK build system.
|
||||
|
||||
* The :command:`export` command gained an ``ANDROID_MK`` option
|
||||
to generate ``Android.mk`` files referencing CMake-built
|
||||
libraries as prebuilts for the Android NDK build system.
|
|
@ -221,10 +221,14 @@ set(SRCS
|
|||
cmExprLexer.cxx
|
||||
cmExprParser.cxx
|
||||
cmExprParserHelper.cxx
|
||||
cmExportBuildAndroidMKGenerator.h
|
||||
cmExportBuildAndroidMKGenerator.cxx
|
||||
cmExportBuildFileGenerator.h
|
||||
cmExportBuildFileGenerator.cxx
|
||||
cmExportFileGenerator.h
|
||||
cmExportFileGenerator.cxx
|
||||
cmExportInstallAndroidMKGenerator.h
|
||||
cmExportInstallAndroidMKGenerator.cxx
|
||||
cmExportInstallFileGenerator.h
|
||||
cmExportInstallFileGenerator.cxx
|
||||
cmExportTryCompileFileGenerator.h
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
|
||||
#include "cmExportSet.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmTargetExport.h"
|
||||
|
||||
cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator()
|
||||
{
|
||||
this->LG = CM_NULLPTR;
|
||||
this->ExportSet = CM_NULLPTR;
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
|
||||
std::ostream& os, const std::string&)
|
||||
{
|
||||
os << "LOCAL_PATH := $(call my-dir)\n\n";
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode(
|
||||
std::ostream&, const std::string&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
|
||||
std::ostream& os, const cmGeneratorTarget* target)
|
||||
{
|
||||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetExportName();
|
||||
os << "include $(CLEAR_VARS)\n";
|
||||
os << "LOCAL_MODULE := ";
|
||||
os << targetName << "\n";
|
||||
os << "LOCAL_SRC_FILES := ";
|
||||
std::string path = target->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
target->GetFullPath(), cmOutputConverter::MAKERULE);
|
||||
os << path << "\n";
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
|
||||
std::ostream&, const std::string&, cmGeneratorTarget const*,
|
||||
ImportPropertyMap const&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
|
||||
std::ostream&, const std::vector<std::string>&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
const cmGeneratorTarget* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties)
|
||||
{
|
||||
std::string config = "";
|
||||
if (this->Configurations.size()) {
|
||||
config = this->Configurations[0];
|
||||
}
|
||||
cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
target, os, properties, cmExportBuildAndroidMKGenerator::BUILD, config);
|
||||
}
|
||||
|
||||
void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
const cmGeneratorTarget* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties, GenerateType type,
|
||||
std::string const& config)
|
||||
{
|
||||
const bool newCMP0022Behavior =
|
||||
target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
|
||||
target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
|
||||
if (!newCMP0022Behavior) {
|
||||
std::ostringstream w;
|
||||
if (type == cmExportBuildAndroidMKGenerator::BUILD) {
|
||||
w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
|
||||
} else {
|
||||
w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
|
||||
}
|
||||
w << " set to OLD for target " << target->Target->GetName() << ". "
|
||||
<< "The export will only work with CMP0022 set to NEW.";
|
||||
target->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||
}
|
||||
if (!properties.empty()) {
|
||||
os << "LOCAL_CPP_FEATURES := rtti exceptions\n";
|
||||
for (ImportPropertyMap::const_iterator pi = properties.begin();
|
||||
pi != properties.end(); ++pi) {
|
||||
if (pi->first == "INTERFACE_COMPILE_OPTIONS") {
|
||||
os << "LOCAL_CPP_FEATURES += ";
|
||||
os << (pi->second) << "\n";
|
||||
} else if (pi->first == "INTERFACE_LINK_LIBRARIES") {
|
||||
// need to look at list in pi->second and see if static or shared
|
||||
// FindTargetToLink
|
||||
// target->GetLocalGenerator()->FindGeneratorTargetToUse()
|
||||
// then add to LOCAL_CPPFLAGS
|
||||
std::vector<std::string> libraries;
|
||||
cmSystemTools::ExpandListArgument(pi->second, libraries);
|
||||
std::string staticLibs;
|
||||
std::string sharedLibs;
|
||||
std::string ldlibs;
|
||||
for (std::vector<std::string>::iterator i = libraries.begin();
|
||||
i != libraries.end(); ++i) {
|
||||
cmGeneratorTarget* gt =
|
||||
target->GetLocalGenerator()->FindGeneratorTargetToUse(*i);
|
||||
if (gt) {
|
||||
|
||||
if (gt->GetType() == cmState::SHARED_LIBRARY ||
|
||||
gt->GetType() == cmState::MODULE_LIBRARY) {
|
||||
sharedLibs += " " + *i;
|
||||
} else {
|
||||
staticLibs += " " + *i;
|
||||
}
|
||||
} else {
|
||||
// evaluate any generator expressions with the current
|
||||
// build type of the makefile
|
||||
cmGeneratorExpression ge;
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
|
||||
std::string evaluated =
|
||||
cge->Evaluate(target->GetLocalGenerator(), config);
|
||||
bool relpath = false;
|
||||
if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
|
||||
relpath = i->substr(0, 3) == "../";
|
||||
}
|
||||
// check for full path or if it already has a -l, or
|
||||
// in the case of an install check for relative paths
|
||||
// if it is full or a link library then use string directly
|
||||
if (cmSystemTools::FileIsFullPath(evaluated) ||
|
||||
evaluated.substr(0, 2) == "-l" || relpath) {
|
||||
ldlibs += " " + evaluated;
|
||||
// if it is not a path and does not have a -l then add -l
|
||||
} else if (!evaluated.empty()) {
|
||||
ldlibs += " -l" + evaluated;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sharedLibs.empty()) {
|
||||
os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n";
|
||||
}
|
||||
if (!staticLibs.empty()) {
|
||||
os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n";
|
||||
}
|
||||
if (!ldlibs.empty()) {
|
||||
os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n";
|
||||
}
|
||||
} else if (pi->first == "INTERFACE_INCLUDE_DIRECTORIES") {
|
||||
std::string includes = pi->second;
|
||||
std::vector<std::string> includeList;
|
||||
cmSystemTools::ExpandListArgument(includes, includeList);
|
||||
os << "LOCAL_EXPORT_C_INCLUDES := ";
|
||||
std::string end;
|
||||
for (std::vector<std::string>::iterator i = includeList.begin();
|
||||
i != includeList.end(); ++i) {
|
||||
os << end << *i;
|
||||
end = "\\\n";
|
||||
}
|
||||
os << "\n";
|
||||
} else {
|
||||
os << "# " << pi->first << " " << (pi->second) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (target->GetType()) {
|
||||
case cmState::SHARED_LIBRARY:
|
||||
case cmState::MODULE_LIBRARY:
|
||||
os << "include $(PREBUILT_SHARED_LIBRARY)\n";
|
||||
break;
|
||||
case cmState::STATIC_LIBRARY:
|
||||
os << "include $(PREBUILT_STATIC_LIBRARY)\n";
|
||||
break;
|
||||
case cmState::EXECUTABLE:
|
||||
case cmState::UTILITY:
|
||||
case cmState::OBJECT_LIBRARY:
|
||||
case cmState::GLOBAL_TARGET:
|
||||
case cmState::INTERFACE_LIBRARY:
|
||||
case cmState::UNKNOWN_LIBRARY:
|
||||
break;
|
||||
}
|
||||
os << "\n";
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#ifndef cmExportBuildAndroidMKGenerator_h
|
||||
#define cmExportBuildAndroidMKGenerator_h
|
||||
|
||||
#include "cmExportBuildFileGenerator.h"
|
||||
#include "cmListFileCache.h"
|
||||
|
||||
class cmExportSet;
|
||||
|
||||
/** \class cmExportBuildAndroidMKGenerator
|
||||
* \brief Generate a file exporting targets from a build tree.
|
||||
*
|
||||
* cmExportBuildAndroidMKGenerator generates a file exporting targets from
|
||||
* a build tree. This exports the targets to the Android ndk build tool
|
||||
* makefile format for prebuilt libraries.
|
||||
*
|
||||
* This is used to implement the EXPORT() command.
|
||||
*/
|
||||
class cmExportBuildAndroidMKGenerator : public cmExportBuildFileGenerator
|
||||
{
|
||||
public:
|
||||
cmExportBuildAndroidMKGenerator();
|
||||
// this is so cmExportInstallAndroidMKGenerator can share this
|
||||
// function as they are almost the same
|
||||
enum GenerateType
|
||||
{
|
||||
BUILD,
|
||||
INSTALL
|
||||
};
|
||||
static void GenerateInterfaceProperties(cmGeneratorTarget const* target,
|
||||
std::ostream& os,
|
||||
const ImportPropertyMap& properties,
|
||||
GenerateType type,
|
||||
std::string const& config);
|
||||
|
||||
protected:
|
||||
// Implement virtual methods from the superclass.
|
||||
virtual void GeneratePolicyHeaderCode(std::ostream&) {}
|
||||
virtual void GeneratePolicyFooterCode(std::ostream&) {}
|
||||
virtual void GenerateImportHeaderCode(std::ostream& os,
|
||||
const std::string& config = "");
|
||||
virtual void GenerateImportFooterCode(std::ostream& os);
|
||||
virtual void GenerateImportTargetCode(std::ostream& os,
|
||||
const cmGeneratorTarget* target);
|
||||
virtual void GenerateExpectedTargetsCode(std::ostream& os,
|
||||
const std::string& expectedTargets);
|
||||
virtual void GenerateImportPropertyCode(std::ostream& os,
|
||||
const std::string& config,
|
||||
cmGeneratorTarget const* target,
|
||||
ImportPropertyMap const& properties);
|
||||
virtual void GenerateMissingTargetsCheckCode(
|
||||
std::ostream& os, const std::vector<std::string>& missingTargets);
|
||||
virtual void GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -18,6 +18,7 @@
|
|||
#include <cmsys/Encoding.hxx>
|
||||
#include <cmsys/RegularExpression.hxx>
|
||||
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
#include "cmExportBuildFileGenerator.h"
|
||||
|
||||
#if defined(__HAIKU__)
|
||||
|
@ -34,6 +35,7 @@ cmExportCommand::cmExportCommand()
|
|||
, Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
|
||||
, Filename(&Helper, "FILE", &ArgumentGroup)
|
||||
, ExportOld(&Helper, "EXPORT_LINK_INTERFACE_LIBRARIES", &ArgumentGroup)
|
||||
, AndroidMKFile(&Helper, "ANDROID_MK")
|
||||
{
|
||||
this->ExportSet = CM_NULLPTR;
|
||||
}
|
||||
|
@ -66,13 +68,18 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
|||
}
|
||||
|
||||
std::string fname;
|
||||
if (!this->Filename.WasFound()) {
|
||||
bool android = false;
|
||||
if (this->AndroidMKFile.WasFound()) {
|
||||
fname = this->AndroidMKFile.GetString();
|
||||
android = true;
|
||||
}
|
||||
if (!this->Filename.WasFound() && fname.empty()) {
|
||||
if (args[0] != "EXPORT") {
|
||||
this->SetError("FILE <filename> option missing.");
|
||||
return false;
|
||||
}
|
||||
fname = this->ExportSetName.GetString() + ".cmake";
|
||||
} else {
|
||||
} else if (fname.empty()) {
|
||||
// Make sure the file has a .cmake extension.
|
||||
if (cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString()) !=
|
||||
".cmake") {
|
||||
|
@ -176,7 +183,12 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
|||
}
|
||||
|
||||
// Setup export file generation.
|
||||
cmExportBuildFileGenerator* ebfg = new cmExportBuildFileGenerator;
|
||||
cmExportBuildFileGenerator* ebfg = CM_NULLPTR;
|
||||
if (android) {
|
||||
ebfg = new cmExportBuildAndroidMKGenerator;
|
||||
} else {
|
||||
ebfg = new cmExportBuildFileGenerator;
|
||||
}
|
||||
ebfg->SetExportFile(fname.c_str());
|
||||
ebfg->SetNamespace(this->Namespace.GetCString());
|
||||
ebfg->SetAppendMode(this->Append.IsEnabled());
|
||||
|
|
|
@ -54,6 +54,7 @@ private:
|
|||
cmCAString Namespace;
|
||||
cmCAString Filename;
|
||||
cmCAEnabler ExportOld;
|
||||
cmCAString AndroidMKFile;
|
||||
|
||||
cmExportSet* ExportSet;
|
||||
|
||||
|
|
|
@ -96,24 +96,8 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
}
|
||||
std::ostream& os = *foutPtr;
|
||||
|
||||
// Protect that file against use with older CMake versions.
|
||||
/* clang-format off */
|
||||
os << "# Generated by CMake\n\n";
|
||||
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "endif()\n";
|
||||
/* clang-format on */
|
||||
|
||||
// Isolate the file policy level.
|
||||
// We use 2.6 here instead of the current version because newer
|
||||
// versions of CMake should be able to export files imported by 2.6
|
||||
// until the import format changes.
|
||||
/* clang-format off */
|
||||
os << "cmake_policy(PUSH)\n"
|
||||
<< "cmake_policy(VERSION 2.6)\n";
|
||||
/* clang-format on */
|
||||
|
||||
// Start with the import file header.
|
||||
this->GeneratePolicyHeaderCode(os);
|
||||
this->GenerateImportHeaderCode(os);
|
||||
|
||||
// Create all the imported targets.
|
||||
|
@ -121,7 +105,7 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
// End with the import file footer.
|
||||
this->GenerateImportFooterCode(os);
|
||||
os << "cmake_policy(POP)\n";
|
||||
this->GeneratePolicyFooterCode(os);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -832,6 +816,31 @@ void cmExportFileGenerator::SetImportLinkProperty(
|
|||
properties[prop] = link_entries;
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
|
||||
{
|
||||
// Protect that file against use with older CMake versions.
|
||||
/* clang-format off */
|
||||
os << "# Generated by CMake\n\n";
|
||||
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "endif()\n";
|
||||
/* clang-format on */
|
||||
|
||||
// Isolate the file policy level.
|
||||
// We use 2.6 here instead of the current version because newer
|
||||
// versions of CMake should be able to export files imported by 2.6
|
||||
// until the import format changes.
|
||||
/* clang-format off */
|
||||
os << "cmake_policy(PUSH)\n"
|
||||
<< "cmake_policy(VERSION 2.6)\n";
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::GeneratePolicyFooterCode(std::ostream& os)
|
||||
{
|
||||
os << "cmake_policy(POP)\n";
|
||||
}
|
||||
|
||||
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
|
||||
const std::string& config)
|
||||
{
|
||||
|
|
|
@ -78,24 +78,27 @@ protected:
|
|||
std::vector<std::string>& missingTargets);
|
||||
|
||||
// Methods to implement export file code generation.
|
||||
void GenerateImportHeaderCode(std::ostream& os,
|
||||
virtual void GeneratePolicyHeaderCode(std::ostream& os);
|
||||
virtual void GeneratePolicyFooterCode(std::ostream& os);
|
||||
virtual void GenerateImportHeaderCode(std::ostream& os,
|
||||
const std::string& config = "");
|
||||
void GenerateImportFooterCode(std::ostream& os);
|
||||
virtual void GenerateImportFooterCode(std::ostream& os);
|
||||
void GenerateImportVersionCode(std::ostream& os);
|
||||
void GenerateImportTargetCode(std::ostream& os,
|
||||
virtual void GenerateImportTargetCode(std::ostream& os,
|
||||
cmGeneratorTarget const* target);
|
||||
void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
|
||||
virtual void GenerateImportPropertyCode(std::ostream& os,
|
||||
const std::string& config,
|
||||
cmGeneratorTarget const* target,
|
||||
ImportPropertyMap const& properties);
|
||||
void GenerateImportedFileChecksCode(
|
||||
virtual void GenerateImportedFileChecksCode(
|
||||
std::ostream& os, cmGeneratorTarget* target,
|
||||
ImportPropertyMap const& properties,
|
||||
const std::set<std::string>& importedLocations);
|
||||
void GenerateImportedFileCheckLoop(std::ostream& os);
|
||||
void GenerateMissingTargetsCheckCode(
|
||||
virtual void GenerateImportedFileCheckLoop(std::ostream& os);
|
||||
virtual void GenerateMissingTargetsCheckCode(
|
||||
std::ostream& os, const std::vector<std::string>& missingTargets);
|
||||
|
||||
void GenerateExpectedTargetsCode(std::ostream& os,
|
||||
virtual void GenerateExpectedTargetsCode(std::ostream& os,
|
||||
const std::string& expectedTargets);
|
||||
|
||||
// Collect properties with detailed information about targets beyond
|
||||
|
@ -140,8 +143,8 @@ protected:
|
|||
ImportPropertyMap& properties);
|
||||
void PopulateCompatibleInterfaceProperties(cmGeneratorTarget* target,
|
||||
ImportPropertyMap& properties);
|
||||
void GenerateInterfaceProperties(cmGeneratorTarget const* target,
|
||||
std::ostream& os,
|
||||
virtual void GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties);
|
||||
void PopulateIncludeDirectoriesInterface(
|
||||
cmTargetExport* target,
|
||||
|
@ -169,7 +172,7 @@ protected:
|
|||
std::vector<std::string>& missingTargets,
|
||||
FreeTargetsReplace replace = NoReplaceFreeTargets);
|
||||
|
||||
void GenerateRequiredCMakeVersion(std::ostream& os,
|
||||
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
|
||||
const char* versionString);
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cmExportInstallAndroidMKGenerator.h"
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmExportSetMap.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmInstallExportGenerator.h"
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmTargetExport.h"
|
||||
|
||||
cmExportInstallAndroidMKGenerator::cmExportInstallAndroidMKGenerator(
|
||||
cmInstallExportGenerator* iegen)
|
||||
: cmExportInstallFileGenerator(iegen)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
|
||||
std::ostream& os, const std::string&)
|
||||
{
|
||||
std::string installDir = this->IEGen->GetDestination();
|
||||
os << "LOCAL_PATH := $(call my-dir)\n";
|
||||
size_t numDotDot = cmSystemTools::CountChar(installDir.c_str(), '/');
|
||||
numDotDot += (installDir.size() > 0) ? 1 : 0;
|
||||
std::string path;
|
||||
for (size_t n = 0; n < numDotDot; n++) {
|
||||
path += "/..";
|
||||
}
|
||||
os << "_IMPORT_PREFIX := "
|
||||
<< "$(LOCAL_PATH)" << path << "\n\n";
|
||||
for (std::vector<cmTargetExport*>::const_iterator tei =
|
||||
this->IEGen->GetExportSet()->GetTargetExports()->begin();
|
||||
tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) {
|
||||
// Collect import properties for this target.
|
||||
cmTargetExport const* te = *tei;
|
||||
if (te->Target->GetType() == cmState::INTERFACE_LIBRARY) {
|
||||
continue;
|
||||
}
|
||||
std::string dest;
|
||||
if (te->LibraryGenerator) {
|
||||
dest = te->LibraryGenerator->GetDestination("");
|
||||
}
|
||||
if (te->ArchiveGenerator) {
|
||||
dest = te->ArchiveGenerator->GetDestination("");
|
||||
}
|
||||
te->Target->Target->SetProperty("__dest", dest.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode(
|
||||
std::ostream& os, const cmGeneratorTarget* target)
|
||||
{
|
||||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetExportName();
|
||||
os << "include $(CLEAR_VARS)\n";
|
||||
os << "LOCAL_MODULE := ";
|
||||
os << targetName << "\n";
|
||||
os << "LOCAL_SRC_FILES := $(_IMPORT_PREFIX)/";
|
||||
os << target->Target->GetProperty("__dest") << "/";
|
||||
std::string config = "";
|
||||
if (this->Configurations.size()) {
|
||||
config = this->Configurations[0];
|
||||
}
|
||||
os << target->GetFullName(config) << "\n";
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateExpectedTargetsCode(
|
||||
std::ostream&, const std::string&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportPropertyCode(
|
||||
std::ostream&, const std::string&, cmGeneratorTarget const*,
|
||||
ImportPropertyMap const&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateMissingTargetsCheckCode(
|
||||
std::ostream&, const std::vector<std::string>&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties)
|
||||
{
|
||||
std::string config = "";
|
||||
if (this->Configurations.size()) {
|
||||
config = this->Configurations[0];
|
||||
}
|
||||
cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
target, os, properties, cmExportBuildAndroidMKGenerator::INSTALL, config);
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::LoadConfigFiles(std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportPrefix(std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateRequiredCMakeVersion(
|
||||
std::ostream&, const char*)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::CleanupTemporaryVariables(
|
||||
std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportedFileCheckLoop(
|
||||
std::ostream&)
|
||||
{
|
||||
}
|
||||
|
||||
void cmExportInstallAndroidMKGenerator::GenerateImportedFileChecksCode(
|
||||
std::ostream&, cmGeneratorTarget*, ImportPropertyMap const&,
|
||||
const std::set<std::string>&)
|
||||
{
|
||||
}
|
||||
|
||||
bool cmExportInstallAndroidMKGenerator::GenerateImportFileConfig(
|
||||
const std::string&, std::vector<std::string>&)
|
||||
{
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#ifndef cmExportInstallAndroidMKGenerator_h
|
||||
#define cmExportInstallAndroidMKGenerator_h
|
||||
|
||||
#include "cmExportInstallFileGenerator.h"
|
||||
|
||||
class cmInstallExportGenerator;
|
||||
class cmInstallTargetGenerator;
|
||||
|
||||
/** \class cmExportInstallAndroidMKGenerator
|
||||
* \brief Generate a file exporting targets from an install tree.
|
||||
*
|
||||
* cmExportInstallAndroidMKGenerator generates files exporting targets from
|
||||
* install an installation tree. The files are placed in a temporary
|
||||
* location for installation by cmInstallExportGenerator. The file format
|
||||
* is for the ndk build system and is a makefile fragment specifing prebuilt
|
||||
* libraries to the ndk build system.
|
||||
*
|
||||
* This is used to implement the INSTALL(EXPORT_ANDROID_MK) command.
|
||||
*/
|
||||
class cmExportInstallAndroidMKGenerator : public cmExportInstallFileGenerator
|
||||
{
|
||||
public:
|
||||
/** Construct with the export installer that will install the
|
||||
files. */
|
||||
cmExportInstallAndroidMKGenerator(cmInstallExportGenerator* iegen);
|
||||
|
||||
protected:
|
||||
// Implement virtual methods from the superclass.
|
||||
virtual void GeneratePolicyHeaderCode(std::ostream&) {}
|
||||
virtual void GeneratePolicyFooterCode(std::ostream&) {}
|
||||
virtual void GenerateImportHeaderCode(std::ostream& os,
|
||||
const std::string& config = "");
|
||||
virtual void GenerateImportFooterCode(std::ostream& os);
|
||||
virtual void GenerateImportTargetCode(std::ostream& os,
|
||||
const cmGeneratorTarget* target);
|
||||
virtual void GenerateExpectedTargetsCode(std::ostream& os,
|
||||
const std::string& expectedTargets);
|
||||
virtual void GenerateImportPropertyCode(std::ostream& os,
|
||||
const std::string& config,
|
||||
cmGeneratorTarget const* target,
|
||||
ImportPropertyMap const& properties);
|
||||
virtual void GenerateMissingTargetsCheckCode(
|
||||
std::ostream& os, const std::vector<std::string>& missingTargets);
|
||||
virtual void GenerateInterfaceProperties(
|
||||
cmGeneratorTarget const* target, std::ostream& os,
|
||||
const ImportPropertyMap& properties);
|
||||
virtual void GenerateImportPrefix(std::ostream& os);
|
||||
virtual void LoadConfigFiles(std::ostream&);
|
||||
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
|
||||
const char* versionString);
|
||||
virtual void CleanupTemporaryVariables(std::ostream&);
|
||||
virtual void GenerateImportedFileCheckLoop(std::ostream& os);
|
||||
virtual void GenerateImportedFileChecksCode(
|
||||
std::ostream& os, cmGeneratorTarget* target,
|
||||
ImportPropertyMap const& properties,
|
||||
const std::set<std::string>& importedLocations);
|
||||
virtual bool GenerateImportFileConfig(const std::string& config,
|
||||
std::vector<std::string>&);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -75,58 +75,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
// Set an _IMPORT_PREFIX variable for import location properties
|
||||
// to reference if they are relative to the install prefix.
|
||||
std::string installPrefix =
|
||||
this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_INSTALL_PREFIX");
|
||||
std::string const& expDest = this->IEGen->GetDestination();
|
||||
if (cmSystemTools::FileIsFullPath(expDest)) {
|
||||
// The export file is being installed to an absolute path so the
|
||||
// package is not relocatable. Use the configured install prefix.
|
||||
/* clang-format off */
|
||||
os <<
|
||||
"# The installation prefix configured by this project.\n"
|
||||
"set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
|
||||
"\n";
|
||||
/* clang-format on */
|
||||
} else {
|
||||
// Add code to compute the installation prefix relative to the
|
||||
// import file location.
|
||||
std::string absDest = installPrefix + "/" + expDest;
|
||||
std::string absDestS = absDest + "/";
|
||||
os << "# Compute the installation prefix relative to this file.\n"
|
||||
<< "get_filename_component(_IMPORT_PREFIX"
|
||||
<< " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||
if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
|
||||
// Handle "/usr move" symlinks created by some Linux distros.
|
||||
/* clang-format off */
|
||||
os <<
|
||||
"# Use original install prefix when loaded through a\n"
|
||||
"# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
|
||||
"get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
|
||||
"get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
|
||||
"if(_realCurr STREQUAL _realOrig)\n"
|
||||
" set(_IMPORT_PREFIX \"" << absDest << "\")\n"
|
||||
"endif()\n"
|
||||
"unset(_realOrig)\n"
|
||||
"unset(_realCurr)\n";
|
||||
/* clang-format on */
|
||||
}
|
||||
std::string dest = expDest;
|
||||
while (!dest.empty()) {
|
||||
os << "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" "
|
||||
"PATH)\n";
|
||||
dest = cmSystemTools::GetFilenamePath(dest);
|
||||
}
|
||||
os << "if(_IMPORT_PREFIX STREQUAL \"/\")\n"
|
||||
<< " set(_IMPORT_PREFIX \"\")\n"
|
||||
<< "endif()\n"
|
||||
<< "\n";
|
||||
}
|
||||
// Compute the relative import prefix for the file
|
||||
this->GenerateImportPrefix(os);
|
||||
|
||||
std::vector<std::string> missingTargets;
|
||||
|
||||
|
@ -204,24 +154,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
this->GenerateRequiredCMakeVersion(os, "2.8.12");
|
||||
}
|
||||
|
||||
// Now load per-configuration properties for them.
|
||||
/* clang-format off */
|
||||
os << "# Load information for each installed configuration.\n"
|
||||
<< "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "file(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< this->GetConfigImportFileGlob() << "\")\n"
|
||||
<< "foreach(f ${CONFIG_FILES})\n"
|
||||
<< " include(${f})\n"
|
||||
<< "endforeach()\n"
|
||||
<< "\n";
|
||||
/* clang-format on */
|
||||
this->LoadConfigFiles(os);
|
||||
|
||||
// Cleanup the import prefix variable.
|
||||
/* clang-format off */
|
||||
os << "# Cleanup temporary variables.\n"
|
||||
<< "set(_IMPORT_PREFIX)\n"
|
||||
<< "\n";
|
||||
/* clang-format on */
|
||||
this->CleanupTemporaryVariables(os);
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
bool result = true;
|
||||
|
@ -242,6 +177,86 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
return result;
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::GenerateImportPrefix(std::ostream& os)
|
||||
{
|
||||
// Set an _IMPORT_PREFIX variable for import location properties
|
||||
// to reference if they are relative to the install prefix.
|
||||
std::string installPrefix =
|
||||
this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_INSTALL_PREFIX");
|
||||
std::string const& expDest = this->IEGen->GetDestination();
|
||||
if (cmSystemTools::FileIsFullPath(expDest)) {
|
||||
// The export file is being installed to an absolute path so the
|
||||
// package is not relocatable. Use the configured install prefix.
|
||||
/* clang-format off */
|
||||
os <<
|
||||
"# The installation prefix configured by this project.\n"
|
||||
"set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
|
||||
"\n";
|
||||
/* clang-format on */
|
||||
} else {
|
||||
// Add code to compute the installation prefix relative to the
|
||||
// import file location.
|
||||
std::string absDest = installPrefix + "/" + expDest;
|
||||
std::string absDestS = absDest + "/";
|
||||
os << "# Compute the installation prefix relative to this file.\n"
|
||||
<< "get_filename_component(_IMPORT_PREFIX"
|
||||
<< " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||
if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
|
||||
cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
|
||||
// Handle "/usr move" symlinks created by some Linux distros.
|
||||
/* clang-format off */
|
||||
os <<
|
||||
"# Use original install prefix when loaded through a\n"
|
||||
"# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
|
||||
"get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
|
||||
"get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
|
||||
"if(_realCurr STREQUAL _realOrig)\n"
|
||||
" set(_IMPORT_PREFIX \"" << absDest << "\")\n"
|
||||
"endif()\n"
|
||||
"unset(_realOrig)\n"
|
||||
"unset(_realCurr)\n";
|
||||
/* clang-format on */
|
||||
}
|
||||
std::string dest = expDest;
|
||||
while (!dest.empty()) {
|
||||
os << "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" "
|
||||
"PATH)\n";
|
||||
dest = cmSystemTools::GetFilenamePath(dest);
|
||||
}
|
||||
os << "if(_IMPORT_PREFIX STREQUAL \"/\")\n"
|
||||
<< " set(_IMPORT_PREFIX \"\")\n"
|
||||
<< "endif()\n"
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::CleanupTemporaryVariables(std::ostream& os)
|
||||
{
|
||||
/* clang-format off */
|
||||
os << "# Cleanup temporary variables.\n"
|
||||
<< "set(_IMPORT_PREFIX)\n"
|
||||
<< "\n";
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
|
||||
{
|
||||
// Now load per-configuration properties for them.
|
||||
/* clang-format off */
|
||||
os << "# Load information for each installed configuration.\n"
|
||||
<< "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "file(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< this->GetConfigImportFileGlob() << "\")\n"
|
||||
<< "foreach(f ${CONFIG_FILES})\n"
|
||||
<< " include(${f})\n"
|
||||
<< "endforeach()\n"
|
||||
<< "\n";
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
|
|
|
@ -80,9 +80,17 @@ protected:
|
|||
std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
|
||||
const std::string& name);
|
||||
|
||||
/** Generate the relative import prefix. */
|
||||
virtual void GenerateImportPrefix(std::ostream&);
|
||||
|
||||
/** Generate the relative import prefix. */
|
||||
virtual void LoadConfigFiles(std::ostream&);
|
||||
|
||||
virtual void CleanupTemporaryVariables(std::ostream&);
|
||||
|
||||
/** Generate a per-configuration file for the targets. */
|
||||
bool GenerateImportFileConfig(const std::string& config,
|
||||
std::vector<std::string>& missingTargets);
|
||||
virtual bool GenerateImportFileConfig(
|
||||
const std::string& config, std::vector<std::string>& missingTargets);
|
||||
|
||||
/** Fill in properties indicating installed file locations. */
|
||||
void SetImportLocationProperty(const std::string& config,
|
||||
|
|
|
@ -83,6 +83,8 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
|
|||
return this->HandleDirectoryMode(args);
|
||||
} else if (args[0] == "EXPORT") {
|
||||
return this->HandleExportMode(args);
|
||||
} else if (args[0] == "EXPORT_ANDROID_MK") {
|
||||
return this->HandleExportAndroidMKMode(args);
|
||||
}
|
||||
|
||||
// Unknown mode.
|
||||
|
@ -1097,6 +1099,100 @@ bool cmInstallCommand::HandleDirectoryMode(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool cmInstallCommand::HandleExportAndroidMKMode(
|
||||
std::vector<std::string> const& args)
|
||||
{
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
// This is the EXPORT mode.
|
||||
cmInstallCommandArguments ica(this->DefaultComponentName);
|
||||
cmCAString exp(&ica.Parser, "EXPORT_ANDROID_MK");
|
||||
cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
|
||||
cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES",
|
||||
&ica.ArgumentGroup);
|
||||
cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
|
||||
exp.Follows(0);
|
||||
|
||||
ica.ArgumentGroup.Follows(&exp);
|
||||
std::vector<std::string> unknownArgs;
|
||||
ica.Parse(&args, &unknownArgs);
|
||||
|
||||
if (!unknownArgs.empty()) {
|
||||
// Unknown argument.
|
||||
std::ostringstream e;
|
||||
e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
|
||||
this->SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ica.Finalize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure there is a destination.
|
||||
if (ica.GetDestination().empty()) {
|
||||
// A destination is required.
|
||||
std::ostringstream e;
|
||||
e << args[0] << " given no DESTINATION!";
|
||||
this->SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the file name.
|
||||
std::string fname = filename.GetString();
|
||||
if (fname.find_first_of(":/\\") != fname.npos) {
|
||||
std::ostringstream e;
|
||||
e << args[0] << " given invalid export file name \"" << fname << "\". "
|
||||
<< "The FILE argument may not contain a path. "
|
||||
<< "Specify the path in the DESTINATION argument.";
|
||||
this->SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the file extension.
|
||||
if (!fname.empty() &&
|
||||
cmSystemTools::GetFilenameLastExtension(fname) != ".mk") {
|
||||
std::ostringstream e;
|
||||
e << args[0] << " given invalid export file name \"" << fname << "\". "
|
||||
<< "The FILE argument must specify a name ending in \".mk\".";
|
||||
this->SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
if (fname.find_first_of(":/\\") != fname.npos) {
|
||||
std::ostringstream e;
|
||||
e << args[0] << " given export name \"" << exp.GetString() << "\". "
|
||||
<< "This name cannot be safely converted to a file name. "
|
||||
<< "Specify a different export name or use the FILE option to set "
|
||||
<< "a file name explicitly.";
|
||||
this->SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
// Use the default name
|
||||
if (fname.empty()) {
|
||||
fname = "Android.mk";
|
||||
}
|
||||
|
||||
cmExportSet* exportSet =
|
||||
this->Makefile->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
|
||||
|
||||
cmInstallGenerator::MessageLevel message =
|
||||
cmInstallGenerator::SelectMessageLevel(this->Makefile);
|
||||
|
||||
// Create the export install generator.
|
||||
cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
|
||||
exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
|
||||
ica.GetConfigurations(), ica.GetComponent().c_str(), message,
|
||||
ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
|
||||
exportOld.IsEnabled(), true);
|
||||
this->Makefile->AddInstallGenerator(exportGenerator);
|
||||
|
||||
return true;
|
||||
#else
|
||||
static_cast<void>(args);
|
||||
this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
|
||||
{
|
||||
// This is the EXPORT mode.
|
||||
|
@ -1203,7 +1299,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
|
|||
exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
|
||||
ica.GetConfigurations(), ica.GetComponent().c_str(), message,
|
||||
ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
|
||||
exportOld.IsEnabled());
|
||||
exportOld.IsEnabled(), false);
|
||||
this->Makefile->AddInstallGenerator(exportGenerator);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
bool HandleFilesMode(std::vector<std::string> const& args);
|
||||
bool HandleDirectoryMode(std::vector<std::string> const& args);
|
||||
bool HandleExportMode(std::vector<std::string> const& args);
|
||||
bool HandleExportAndroidMKMode(std::vector<std::string> const& args);
|
||||
bool MakeFilesFullPath(const char* modeName,
|
||||
const std::vector<std::string>& relFiles,
|
||||
std::vector<std::string>& absFiles);
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cmInstallExportAndroidMKGenerator.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cmExportInstallFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmInstallFilesGenerator.h"
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmake.h"
|
||||
|
||||
cmInstallExportAndroidMKGenerator::cmInstallExportAndroidMKGenerator(
|
||||
cmExportSet* exportSet, const char* destination,
|
||||
const char* file_permissions, std::vector<std::string> const& configurations,
|
||||
const char* component, MessageLevel message, bool exclude_from_all,
|
||||
const char* filename, const char* name_space, bool exportOld)
|
||||
: cmInstallExportGenerator(exportSet, destination, file_permissions,
|
||||
configurations, component, message,
|
||||
exclude_from_all, filename, name_space, exportOld)
|
||||
{
|
||||
}
|
||||
|
||||
cmInstallExportAndroidMKGenerator::~cmInstallExportAndroidMKGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg)
|
||||
{
|
||||
this->LocalGenerator = lg;
|
||||
this->ExportSet->Compute(lg);
|
||||
}
|
||||
|
||||
void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os)
|
||||
{
|
||||
// Skip empty sets.
|
||||
if (ExportSet->GetTargetExports()->empty()) {
|
||||
std::ostringstream e;
|
||||
e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName()
|
||||
<< "\"";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the temporary directory in which to store the files.
|
||||
this->ComputeTempDir();
|
||||
cmSystemTools::MakeDirectory(this->TempDir.c_str());
|
||||
|
||||
// Construct a temporary location for the file.
|
||||
this->MainImportFile = this->TempDir;
|
||||
this->MainImportFile += "/";
|
||||
this->MainImportFile += this->FileName;
|
||||
|
||||
// Generate the import file for this export set.
|
||||
this->EFGen->SetExportFile(this->MainImportFile.c_str());
|
||||
this->EFGen->SetNamespace(this->Namespace);
|
||||
this->EFGen->SetExportOld(this->ExportOld);
|
||||
if (this->ConfigurationTypes->empty()) {
|
||||
if (!this->ConfigurationName.empty()) {
|
||||
this->EFGen->AddConfiguration(this->ConfigurationName);
|
||||
} else {
|
||||
this->EFGen->AddConfiguration("");
|
||||
}
|
||||
} else {
|
||||
for (std::vector<std::string>::const_iterator ci =
|
||||
this->ConfigurationTypes->begin();
|
||||
ci != this->ConfigurationTypes->end(); ++ci) {
|
||||
this->EFGen->AddConfiguration(*ci);
|
||||
}
|
||||
}
|
||||
this->EFGen->GenerateImportFile();
|
||||
|
||||
// Perform the main install script generation.
|
||||
this->cmInstallGenerator::GenerateScript(os);
|
||||
}
|
||||
|
||||
void cmInstallExportAndroidMKGenerator::GenerateScriptConfigs(
|
||||
std::ostream& os, Indent const& indent)
|
||||
{
|
||||
// Create the main install rules first.
|
||||
this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
|
||||
|
||||
// Now create a configuration-specific install rule for the import
|
||||
// file of each configuration.
|
||||
std::vector<std::string> files;
|
||||
for (std::map<std::string, std::string>::const_iterator i =
|
||||
this->EFGen->GetConfigImportFiles().begin();
|
||||
i != this->EFGen->GetConfigImportFiles().end(); ++i) {
|
||||
files.push_back(i->second);
|
||||
std::string config_test = this->CreateConfigTest(i->first);
|
||||
os << indent << "if(" << config_test << ")\n";
|
||||
this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
|
||||
false, this->FilePermissions.c_str(), CM_NULLPTR,
|
||||
CM_NULLPTR, CM_NULLPTR, indent.Next());
|
||||
os << indent << "endif()\n";
|
||||
files.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void cmInstallExportAndroidMKGenerator::GenerateScriptActions(
|
||||
std::ostream& os, Indent const& indent)
|
||||
{
|
||||
// Remove old per-configuration export files if the main changes.
|
||||
std::string installedDir = "$ENV{DESTDIR}";
|
||||
installedDir += this->ConvertToAbsoluteDestination(this->Destination);
|
||||
installedDir += "/";
|
||||
std::string installedFile = installedDir;
|
||||
installedFile += this->FileName;
|
||||
os << indent << "if(EXISTS \"" << installedFile << "\")\n";
|
||||
Indent indentN = indent.Next();
|
||||
Indent indentNN = indentN.Next();
|
||||
Indent indentNNN = indentNN.Next();
|
||||
/* clang-format off */
|
||||
os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
|
||||
<< indentN << " \"" << installedFile << "\"\n"
|
||||
<< indentN << " \"" << this->MainImportFile << "\")\n";
|
||||
os << indentN << "if(EXPORT_FILE_CHANGED)\n";
|
||||
os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir
|
||||
<< this->EFGen->GetConfigImportFileGlob() << "\")\n";
|
||||
os << indentNN << "if(OLD_CONFIG_FILES)\n";
|
||||
os << indentNNN << "message(STATUS \"Old export file \\\"" << installedFile
|
||||
<< "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
|
||||
os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n";
|
||||
os << indentNN << "endif()\n";
|
||||
os << indentN << "endif()\n";
|
||||
os << indent << "endif()\n";
|
||||
/* clang-format on */
|
||||
|
||||
// Install the main export file.
|
||||
std::vector<std::string> files;
|
||||
files.push_back(this->MainImportFile);
|
||||
this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
|
||||
false, this->FilePermissions.c_str(), CM_NULLPTR,
|
||||
CM_NULLPTR, CM_NULLPTR, indent);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#ifndef cmInstallExportAndroidMKGenerator_h
|
||||
#define cmInstallExportAndroidMKGenerator_h
|
||||
|
||||
#include "cmInstallExportGenerator.h"
|
||||
|
||||
class cmExportInstallFileGenerator;
|
||||
class cmInstallFilesGenerator;
|
||||
class cmInstallTargetGenerator;
|
||||
class cmExportSet;
|
||||
class cmMakefile;
|
||||
|
||||
/** \class cmInstallExportAndroidMKGenerator
|
||||
* \brief Generate rules for creating an export files.
|
||||
*/
|
||||
class cmInstallExportAndroidMKGenerator : public cmInstallExportGenerator
|
||||
{
|
||||
public:
|
||||
cmInstallExportAndroidMKGenerator(
|
||||
cmExportSet* exportSet, const char* dest, const char* file_permissions,
|
||||
const std::vector<std::string>& configurations, const char* component,
|
||||
MessageLevel message, bool exclude_from_all, const char* filename,
|
||||
const char* name_space, bool exportOld);
|
||||
~cmInstallExportAndroidMKGenerator();
|
||||
|
||||
void Compute(cmLocalGenerator* lg);
|
||||
|
||||
protected:
|
||||
virtual void GenerateScript(std::ostream& os);
|
||||
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
|
||||
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
|
||||
void GenerateImportFile(cmExportSet const* exportSet);
|
||||
void GenerateImportFile(const char* config, cmExportSet const* exportSet);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,6 +16,9 @@
|
|||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
#include "cmExportInstallAndroidMKGenerator.h"
|
||||
#endif
|
||||
#include "cmExportInstallFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmInstallType.h"
|
||||
|
@ -27,7 +30,7 @@ cmInstallExportGenerator::cmInstallExportGenerator(
|
|||
cmExportSet* exportSet, const char* destination,
|
||||
const char* file_permissions, std::vector<std::string> const& configurations,
|
||||
const char* component, MessageLevel message, bool exclude_from_all,
|
||||
const char* filename, const char* name_space, bool exportOld)
|
||||
const char* filename, const char* name_space, bool exportOld, bool android)
|
||||
: cmInstallGenerator(destination, configurations, component, message,
|
||||
exclude_from_all)
|
||||
, ExportSet(exportSet)
|
||||
|
@ -37,7 +40,13 @@ cmInstallExportGenerator::cmInstallExportGenerator(
|
|||
, ExportOld(exportOld)
|
||||
, LocalGenerator(CM_NULLPTR)
|
||||
{
|
||||
if (android) {
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
this->EFGen = new cmExportInstallAndroidMKGenerator(this);
|
||||
#endif
|
||||
} else {
|
||||
this->EFGen = new cmExportInstallFileGenerator(this);
|
||||
}
|
||||
exportSet->AddInstallation(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ public:
|
|||
const std::vector<std::string>& configurations,
|
||||
const char* component, MessageLevel message,
|
||||
bool exclude_from_all, const char* filename,
|
||||
const char* name_space, bool exportOld);
|
||||
const char* name_space, bool exportOld,
|
||||
bool android);
|
||||
~cmInstallExportGenerator() CM_OVERRIDE;
|
||||
|
||||
cmExportSet* GetExportSet() { return this->ExportSet; }
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# This file does a regex file compare on the generated
|
||||
# Android.mk files from the AndroidMK test
|
||||
|
||||
macro(compare_file_to_expected file expected_file)
|
||||
file(READ "${file}" ANDROID_MK)
|
||||
# clean up new lines
|
||||
string(REGEX REPLACE "\r\n" "\n" ANDROID_MK "${ANDROID_MK}")
|
||||
string(REGEX REPLACE "\n+$" "" ANDROID_MK "${ANDROID_MK}")
|
||||
# read in the expected regex file
|
||||
file(READ "${expected_file}" expected)
|
||||
# clean up new lines
|
||||
string(REGEX REPLACE "\r\n" "\n" expected "${expected}")
|
||||
string(REGEX REPLACE "\n+$" "" expected "${expected}")
|
||||
# compare the file to the expected regex and if there is not a match
|
||||
# put an error message in RunCMake_TEST_FAILED
|
||||
if(NOT "${ANDROID_MK}" MATCHES "${expected}")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"${file} does not match ${expected_file}:
|
||||
|
||||
Android.mk contents = [\n${ANDROID_MK}\n]
|
||||
Expected = [\n${expected}\n]")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
compare_file_to_expected(
|
||||
"${RunCMake_BINARY_DIR}/AndroidMK-build/Android.mk"
|
||||
"${RunCMake_TEST_SOURCE_DIR}/expectedBuildAndroidMK.txt")
|
||||
compare_file_to_expected(
|
||||
"${RunCMake_BINARY_DIR}/AndroidMK-build/CMakeFiles/Export/share/ndk-modules/Android.mk"
|
||||
"${RunCMake_TEST_SOURCE_DIR}/expectedInstallAndroidMK.txt")
|
|
@ -0,0 +1,11 @@
|
|||
project(build)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
add_library(foo foo.cxx)
|
||||
add_library(car foo.cxx)
|
||||
add_library(bar foo.cxx)
|
||||
add_library(dog foo.cxx)
|
||||
target_link_libraries(foo car bar dog debug -lm)
|
||||
export(TARGETS bar dog car foo ANDROID_MK
|
||||
${build_BINARY_DIR}/Android.mk)
|
||||
install(TARGETS bar dog car foo DESTINATION lib EXPORT myexp)
|
||||
install(EXPORT_ANDROID_MK myexp DESTINATION share/ndk-modules)
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
project(${RunCMake_TEST} NONE) # or languages needed
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,2 @@
|
|||
include(RunCMake)
|
||||
run_cmake(AndroidMK)
|
|
@ -0,0 +1,23 @@
|
|||
LOCAL_PATH.*call my-dir.*
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*bar
|
||||
LOCAL_SRC_FILES.*bar.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
.*
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*dog
|
||||
LOCAL_SRC_FILES.*.*dog.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
.*
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*car
|
||||
LOCAL_SRC_FILES.*.*car.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
.*
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*foo
|
||||
LOCAL_SRC_FILES.*.*foo.*
|
||||
LOCAL_CPP_FEATURES.*rtti exceptions
|
||||
LOCAL_STATIC_LIBRARIES.*car bar dog
|
||||
LOCAL_EXPORT_LDLIBS := -lm
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
|
@ -0,0 +1,25 @@
|
|||
LOCAL_PATH.*call my-dir.*
|
||||
_IMPORT_PREFIX.*LOCAL_PATH./../..
|
||||
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*bar
|
||||
LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*bar.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
include.*CLEAR_VARS.
|
||||
LOCAL_MODULE.*dog
|
||||
LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*dog.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*car
|
||||
LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*car.*
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*foo
|
||||
LOCAL_SRC_FILES.*_IMPORT_PREFIX\)/lib.*foo.*
|
||||
LOCAL_CPP_FEATURES.*rtti exceptions
|
||||
LOCAL_STATIC_LIBRARIES.*car bar dog
|
||||
LOCAL_EXPORT_LDLIBS := -lm
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
|
@ -0,0 +1,3 @@
|
|||
void foo()
|
||||
{
|
||||
}
|
|
@ -331,6 +331,8 @@ add_RunCMake_test_group(CPack "DEB;RPM;TGZ")
|
|||
# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
|
||||
add_RunCMake_test(AutoExportDll)
|
||||
|
||||
add_RunCMake_test(AndroidMK)
|
||||
|
||||
if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
|
||||
if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
||||
message(FATAL_ERROR "Android tests supported only by Makefile and Ninja generators")
|
||||
|
|
Loading…
Reference in New Issue