aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Schaefer <cdtdoug@gmail.com>2011-06-02 11:00:10 -0400
committerDoug Schaefer <cdtdoug@gmail.com>2011-06-29 10:12:06 -0400
commit29d78b7a0e6fc7e0be8be1afc594ffd3f6b26c36 (patch)
treed8216989a97b9c9841132d39c2e06732c206ba17
parent45a48ebcea82f786352df2dd53e31bdbb3270b46 (diff)
downloadsdk-29d78b7a0e6fc7e0be8be1afc594ffd3f6b26c36.zip
sdk-29d78b7a0e6fc7e0be8be1afc594ffd3f6b26c36.tar.gz
sdk-29d78b7a0e6fc7e0be8be1afc594ffd3f6b26c36.tar.bz2
New plug-in supporting NDK with CDT
Provides the Add Native Support menu item for Android projects. Provides build integration for ndk-build and Android toolchains. No debug support yet, but that's in the works. Includes a new feature for this that brings in CDT at install time. Scanner Discovery currently doesn't work on Windows but does on Mac/Linux. Fixed to adhere to Android coding standards. Change-Id: I26ddd622aaa3256e336804b1ace8163ed742e9b2 Signed-off-by: Doug Schaefer <cdtdoug@gmail.com>
-rw-r--r--eclipse/features/com.android.ide.eclipse.adt.ndk/.project17
-rw-r--r--eclipse/features/com.android.ide.eclipse.adt.ndk/build.properties1
-rw-r--r--eclipse/features/com.android.ide.eclipse.adt.ndk/feature.xml117
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/.classpath7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/.project28
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/.settings/org.eclipse.jdt.core.prefs64
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/META-INF/MANIFEST.MF21
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/MODULE_LICENSE_EPL0
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/NOTICE224
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.html106
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.ini2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt.ndk/about.properties7
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/build.properties12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.c0
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.cpp0
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/android-32.pngbin0 -> 2446 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/obj16/c_app.gifbin0 -> 606 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/debugger_tab.gifbin0 -> 348 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/startup_tab.gifbin0 -> 527 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/plugin.xml143
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Activator.java85
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Messages.java63
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/NdkManager.java74
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/actions/AddNativeAction.java66
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkCommandLauncher.java48
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkEnvSupplier.java111
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveredPathInfo.java199
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveryUpdater.java315
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkScannerInfoCollector.java93
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/messages.properties16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferenceInitializer.java33
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferencePage.java92
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SetFolders.java105
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SimpleFile.java125
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/TemplatedInputStream.java87
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizard.java107
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizardPage.java81
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/NdkWizardHandler.java41
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/addNdkSupport.xml33
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/main.cpp1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/tAndroid.mk8
41 files changed, 2532 insertions, 0 deletions
diff --git a/eclipse/features/com.android.ide.eclipse.adt.ndk/.project b/eclipse/features/com.android.ide.eclipse.adt.ndk/.project
new file mode 100644
index 0000000..4fc0b1d
--- /dev/null
+++ b/eclipse/features/com.android.ide.eclipse.adt.ndk/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>adt-ndk-feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/eclipse/features/com.android.ide.eclipse.adt.ndk/build.properties b/eclipse/features/com.android.ide.eclipse.adt.ndk/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/eclipse/features/com.android.ide.eclipse.adt.ndk/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/eclipse/features/com.android.ide.eclipse.adt.ndk/feature.xml b/eclipse/features/com.android.ide.eclipse.adt.ndk/feature.xml
new file mode 100644
index 0000000..d8ef2dd
--- /dev/null
+++ b/eclipse/features/com.android.ide.eclipse.adt.ndk/feature.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="com.android.ide.eclipse.adt.ndk"
+ label="Android Native Development Tools"
+ version="13.0.0.qualifier"
+ provider-name="The Android Open Source Project">
+
+ <description>
+ Android Native Developer Tools.
+ </description>
+
+ <license url="http://www.eclipse.org/org/documents/epl-v10.php">
+ Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+&quot;Contribution&quot; means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+&quot;Contributor&quot; means any person or entity that distributes the Program.
+
+&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
+
+&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+ </license>
+
+ <url>
+ <update label="Android Update Site" url="https://dl-ssl.google.com/android/eclipse/"/>
+ </url>
+
+ <requires>
+ <import feature="org.eclipse.cdt"/>
+ </requires>
+
+ <plugin
+ id="com.android.ide.eclipse.adt.ndk"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.classpath b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.classpath
new file mode 100644
index 0000000..1fa3e68
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.project b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.project
new file mode 100644
index 0000000..5771a44
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>adt-ndk</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.settings/org.eclipse.jdt.core.prefs b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..f4696e4
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,64 @@
+#Wed Mar 16 15:10:40 PDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8cdfc18
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ADT CDT Integration
+Bundle-SymbolicName: com.android.ide.eclipse.adt.ndk;singleton:=true
+Bundle-Version: 13.0.0.qualifier
+Bundle-Activator: com.android.ide.eclipse.adt.ndk.internal.Activator
+Bundle-Vendor: The Android Open Source Project
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.ui,
+ org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.cdt.core,
+ org.eclipse.cdt.ui,
+ org.eclipse.cdt.managedbuilder.core,
+ org.eclipse.cdt.managedbuilder.ui,
+ org.eclipse.cdt.dsf.gdb,
+ org.eclipse.cdt.debug.ui,
+ org.eclipse.cdt.launch,
+ com.android.ide.eclipse.adt
+Bundle-ActivationPolicy: lazy
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/MODULE_LICENSE_EPL b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/MODULE_LICENSE_EPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/MODULE_LICENSE_EPL
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/NOTICE b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/NOTICE
new file mode 100644
index 0000000..49c101d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/NOTICE
@@ -0,0 +1,224 @@
+*Eclipse Public License - v 1.0*
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+*1. DEFINITIONS*
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and
+are distributed by that particular Contributor. A Contribution
+'originates' from a Contributor if it was added to the Program by such
+Contributor itself or anyone acting on such Contributor's behalf.
+Contributions do not include additions to the Program which: (i) are
+separate modules of software distributed in conjunction with the Program
+under their own license agreement, and (ii) are not derivative works of
+the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+*2. GRANT OF RIGHTS*
+
+a) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free copyright
+license to reproduce, prepare derivative works of, publicly display,
+publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and
+object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free patent license
+under Licensed Patents to make, use, sell, offer to sell, import and
+otherwise transfer the Contribution of such Contributor, if any, in
+source code and object code form. This patent license shall apply to the
+combination of the Contribution and the Program if, at the time the
+Contribution is added by the Contributor, such addition of the
+Contribution causes such combination to be covered by the Licensed
+Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+
+*3. REQUIREMENTS*
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties
+and conditions, express and implied, including warranties or conditions
+of title and non-infringement, and implied warranties or conditions of
+merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+*4. COMMERCIAL DISTRIBUTION*
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program, the
+Contributor who includes the Program in a commercial product offering
+should do so in a manner which does not create potential liability for
+other Contributors. Therefore, if a Contributor includes the Program in
+a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the
+Program in a commercial product offering. The obligations in this
+section do not apply to any claims or Losses relating to any actual or
+alleged intellectual property infringement. In order to qualify, an
+Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial
+Contributor to control, and cooperate with the Commercial Contributor
+in, the defense and any related settlement negotiations. The Indemnified
+Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+*5. NO WARRANTY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
+OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. Each Recipient is solely responsible for
+determining the appropriateness of using and distributing the Program
+and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program
+errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+*6. DISCLAIMER OF LIABILITY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. GENERAL*
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including
+a cross-claim or counterclaim in a lawsuit) alleging that the Program
+itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails
+to comply with any of the material terms or conditions of this Agreement
+and does not cure such failure in a reasonable period of time after
+becoming aware of such noncompliance. If all Recipient's rights under
+this Agreement terminate, Recipient agrees to cease use and distribution
+of the Program as soon as reasonably practicable. However, Recipient's
+obligations under this Agreement and any licenses granted by Recipient
+relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and may
+only be modified in the following manner. The Agreement Steward reserves
+the right to publish new versions (including revisions) of this
+Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the
+initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is
+published, Contributor may elect to distribute the Program (including
+its Contributions) under the new version. Except as expressly stated in
+Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
+to the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in
+the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to
+this Agreement will bring a legal action under this Agreement more than
+one year after the cause of action arose. Each party waives its rights
+to a jury trial in any resulting litigation.
+
+
+
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.html b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.html
new file mode 100644
index 0000000..bc621cb
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>September 19, 2010</p>
+<h3>License</h3>
+
+<pre>
+ Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+&quot;Contribution&quot; means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+&quot;Contributor&quot; means any person or entity that distributes the Program.
+
+&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
+
+&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+
+</pre>
+
+</body>
+</html>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.ini b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.ini
new file mode 100644
index 0000000..2d7cdaa
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.ini
@@ -0,0 +1,2 @@
+aboutText=%blurb
+featureImage=icons/android-32.png \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.properties b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.properties
new file mode 100755
index 0000000..34218e9
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/about.properties
@@ -0,0 +1,7 @@
+blurb=Android Development Toolkit\n\
+\n\
+Version\: {featureVersion}\n\
+\n\
+(c) Copyright 2007-2011 The Android Open Source Project. All rights reserved.\n\
+Visit http://developer.android.com/sdk/eclipse-adt.html
+
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/build.properties b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/build.properties
new file mode 100644
index 0000000..4842ac1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/build.properties
@@ -0,0 +1,12 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ templates/,\
+ discovery/,\
+ NOTICE,\
+ about.html,\
+ about.ini,\
+ about.properties
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.c b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.c
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.cpp b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/discovery/test.cpp
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/android-32.png b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/android-32.png
new file mode 100644
index 0000000..4e0cc13
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/android-32.png
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/obj16/c_app.gif b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/obj16/c_app.gif
new file mode 100644
index 0000000..504ef50
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/obj16/c_app.gif
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/debugger_tab.gif b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/debugger_tab.gif
new file mode 100644
index 0000000..d90a29f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/debugger_tab.gif
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/startup_tab.gif b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/startup_tab.gif
new file mode 100644
index 0000000..7b3a92e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/icons/view16/startup_tab.gif
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/plugin.xml
new file mode 100644
index 0000000..5179dd6
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/plugin.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.cdt.managedbuilder.core.buildDefinitions">
+ <managedBuildRevision
+ fileVersion="4.0.0">
+ </managedBuildRevision>
+ <toolChain
+ configurationEnvironmentSupplier="com.android.ide.eclipse.adt.ndk.internal.build.NdkEnvSupplier"
+ id="com.android.toolchain.gcc"
+ isAbstract="false"
+ name="Android GCC">
+ <targetPlatform
+ binaryParser="org.eclipse.cdt.core.ELF"
+ id="com.android.targetPlatform"
+ isAbstract="false">
+ </targetPlatform>
+ <builder
+ cleanBuildTarget="clean"
+ command="ndk-build"
+ commandLauncher="com.android.ide.eclipse.adt.ndk.internal.build.NdkCommandLauncher"
+ id="com.android.builder"
+ isAbstract="false"
+ isVariableCaseSensitive="false"
+ name="Android Builder">
+ </builder>
+ <tool
+ id="com.android.gcc.compiler"
+ isAbstract="false"
+ name="Android GCC Compiler"
+ natureFilter="both">
+ <option
+ browseType="directory"
+ id="com.android.gcc.option.includePath"
+ isAbstract="false"
+ resourceFilter="all"
+ valueType="includePath">
+ </option>
+ <inputType
+ id="com.android.gcc.inputType"
+ scannerConfigDiscoveryProfileId="com.android.AndroidPerProjectProfile"
+ sources="c,cpp">
+ </inputType>
+ </tool>
+ </toolChain>
+ </extension>
+ <extension
+ id="com.android.AndroidPerProjectProfile"
+ name="Android Per Project Profile"
+ point="org.eclipse.cdt.make.core.ScannerConfigurationDiscoveryProfile">
+ <scannerInfoCollector
+ class="com.android.ide.eclipse.adt.ndk.internal.discovery.NdkScannerInfoCollector"
+ scope="project">
+ </scannerInfoCollector>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.core.templateProcessTypes">
+ <processType
+ name="SetFolders"
+ processRunner="com.android.ide.eclipse.adt.ndk.internal.templates.SetFolders">
+ <simple
+ name="projectName">
+ </simple>
+ <simpleArray
+ name="sourceFolders">
+ </simpleArray>
+ <simpleArray
+ name="outputFolders">
+ </simpleArray>
+ </processType>
+ <processType
+ name="SimpleFile"
+ processRunner="com.android.ide.eclipse.adt.ndk.internal.templates.SimpleFile">
+ <simple
+ name="projectName">
+ </simple>
+ <complexArray
+ name="files">
+ <baseType>
+ <simple
+ name="source">
+ </simple>
+ <simple
+ name="destination">
+ </simple></baseType>
+ </complexArray>
+ </processType>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.core.templates">
+ <template
+ id="com.android.ide.eclipse.adt.ndk.addNdkSupport"
+ location="templates/addNdkSupport.xml"
+ projectType="none">
+ </template>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="com.android.ide.eclipse.preferences.main"
+ class="com.android.ide.eclipse.adt.ndk.internal.preferences.NdkPreferencePage"
+ id="org.eclipse.cdt.android.page"
+ name="NDK">
+ </page>
+ </extension>
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ adaptable="true"
+ id="com.android.ide.eclipse.adt.ndk.projectContribution"
+ objectClass="org.eclipse.core.resources.IProject">
+ <visibility>
+ <and>
+ <objectState
+ name="projectNature"
+ value="com.android.ide.eclipse.adt.AndroidNature">
+ </objectState>
+ <not>
+ <objectState
+ name="projectNature"
+ value="org.eclipse.cdt.core.cnature">
+ </objectState>
+ </not>
+ </and>
+ </visibility>
+ <action
+ class="com.android.ide.eclipse.adt.ndk.internal.actions.AddNativeAction"
+ enablesFor="1"
+ id="org.eclipse.cdt.android.action1"
+ label="Add Native Support..."
+ menubarPath="com.android.ide.eclipse.adt.AndroidTools/ndk">
+ </action>
+ </objectContribution>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="com.android.ide.eclipse.adt.ndk.internal.preferences.NdkPreferenceInitializer">
+ </initializer>
+ </extension>
+
+</plugin>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Activator.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Activator.java
new file mode 100644
index 0000000..48adf11
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Activator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import java.net.URL;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "com.android.ide.eclipse.adt.ndk"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator mPlugin;
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ mPlugin = this;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ mPlugin = null;
+ super.stop(context);
+ }
+
+ public static Activator getDefault() {
+ return mPlugin;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T getService(Class<T> clazz) {
+ BundleContext context = mPlugin.getBundle().getBundleContext();
+ ServiceReference ref = context.getServiceReference(clazz.getName());
+ return (ref != null) ? (T) context.getService(ref) : null;
+ }
+
+ public static Bundle getBundle(String id) {
+ for (Bundle bundle : mPlugin.getBundle().getBundleContext().getBundles()) {
+ if (bundle.getSymbolicName().equals(id)) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ public static IStatus newStatus(Exception e) {
+ return new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e);
+ }
+
+ public static void log(Exception e) {
+ mPlugin.getLog().log(newStatus(e));
+ }
+
+ public static URL findFile(IPath path) {
+ return FileLocator.find(mPlugin.getBundle(), path, null);
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Messages.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Messages.java
new file mode 100644
index 0000000..f8dbcb4
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/Messages.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.ndk.internal.messages"; //$NON-NLS-1$
+
+ public static String AddNativeWizardPage_Description;
+
+ public static String AddNativeWizardPage_LibraryName;
+
+ public static String AddNativeWizardPage_Location_not_valid;
+
+ public static String AddNativeWizardPage_Title;
+
+ public static String NDKPreferencePage_Location;
+
+ public static String NDKPreferencePage_not_a_valid_directory;
+
+ public static String NDKPreferencePage_not_a_valid_NDK_directory;
+
+ public static String NDKPreferencePage_Preferences;
+
+ public static String SetFolders_Missing_project_name;
+
+ public static String SetFolders_No_folders;
+
+ public static String SetFolders_Project_does_not_exist;
+
+ public static String SimpleFile_Bad_file_operation;
+
+ public static String SimpleFile_Bundle_not_found;
+
+ public static String SimpleFile_Could_not_fine_source;
+
+ public static String SimpleFile_No_project_name;
+
+ public static String SimpleFile_Project_does_not_exist;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/NdkManager.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/NdkManager.java
new file mode 100644
index 0000000..8541020
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/NdkManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010, 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal;
+
+import org.eclipse.cdt.core.templateengine.TemplateCore;
+import org.eclipse.cdt.core.templateengine.TemplateEngine;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import java.io.File;
+import java.util.Map;
+
+public class NdkManager {
+
+ public static final String NDK_LOCATION = "ndkLocation"; //$NON-NLS-1$
+
+ public static final String LIBRARY_NAME = "libraryName"; //$NON-NLS-1$
+
+ public static String getNdkLocation() {
+ return Activator.getDefault().getPreferenceStore().getString(NDK_LOCATION);
+ }
+
+ public static boolean isNdkLocationValid() {
+ String location = getNdkLocation();
+ if (location.length() == 0)
+ return false;
+
+ return isValidNdkLocation(location);
+ }
+
+ public static boolean isValidNdkLocation(String location) {
+ File dir = new File(location);
+ if (!dir.isDirectory())
+ return false;
+
+ // Must contain the ndk-build script which we call to build
+ if (!new File(dir, "ndk-build").isFile()) //$NON-NLS-1$
+ return false;
+
+ return true;
+ }
+
+ public static void addNativeSupport(final IProject project, Map<String, String> templateArgs,
+ IProgressMonitor monitor)
+ throws CoreException {
+ // Launch our template to set up the project contents
+ TemplateCore template = TemplateEngine.getDefault().getTemplateById("AddNdkSupport"); //$NON-NLS-1$
+ Map<String, String> valueStore = template.getValueStore();
+ valueStore.put("projectName", project.getName()); //$NON-NLS-1$
+ valueStore.putAll(templateArgs);
+ template.executeTemplateProcesses(monitor, false);
+
+ // refresh project resources
+ project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 10));
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/actions/AddNativeAction.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/actions/AddNativeAction.java
new file mode 100644
index 0000000..fdb96b6
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/actions/AddNativeAction.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.actions;
+
+import com.android.ide.eclipse.adt.ndk.internal.wizards.AddNativeWizard;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class AddNativeAction implements IObjectActionDelegate {
+
+ private IWorkbenchPart mPart;
+ private ISelection mSelection;
+
+ public void run(IAction action) {
+ IProject project = null;
+ if (mSelection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) mSelection;
+ if (ss.size() == 1) {
+ Object obj = ss.getFirstElement();
+ if (obj instanceof IProject) {
+ project = (IProject) obj;
+ } else if (obj instanceof PlatformObject) {
+ project = (IProject) ((PlatformObject) obj).getAdapter(IProject.class);
+ }
+ }
+ }
+
+ if (project != null) {
+ AddNativeWizard wizard = new AddNativeWizard(project, mPart.getSite()
+ .getWorkbenchWindow());
+ WizardDialog dialog = new WizardDialog(mPart.getSite().getShell(), wizard);
+ dialog.open();
+ }
+
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ mSelection = selection;
+ }
+
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ mPart = targetPart;
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkCommandLauncher.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkCommandLauncher.java
new file mode 100644
index 0000000..db3a8f1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkCommandLauncher.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.build;
+
+import com.android.ide.eclipse.adt.ndk.internal.NdkManager;
+
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+
+public class NdkCommandLauncher extends CommandLauncher {
+
+ @Override
+ public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory,
+ IProgressMonitor monitor)
+ throws CoreException {
+ if (!commandPath.isAbsolute())
+ commandPath = new Path(NdkManager.getNdkLocation()).append(commandPath);
+
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ String[] newargs = new String[args.length + 1];
+ newargs[0] = commandPath.toOSString();
+ System.arraycopy(args, 0, newargs, 1, args.length);
+ commandPath = new Path("sh"); //$NON-NLS-1$
+ args = newargs;
+ }
+
+ return super.execute(commandPath, args, env, changeToDirectory, monitor);
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkEnvSupplier.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkEnvSupplier.java
new file mode 100644
index 0000000..3259a4e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/build/NdkEnvSupplier.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.build;
+
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
+import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
+import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
+import org.eclipse.core.runtime.Platform;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+public class NdkEnvSupplier implements IConfigurationEnvironmentVariableSupplier {
+
+ private static Map<String, IBuildEnvironmentVariable> mEnvVars;
+
+ private synchronized void init() {
+ if (mEnvVars != null)
+ return;
+
+ mEnvVars = new HashMap<String, IBuildEnvironmentVariable>();
+
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ // For Windows, need to add a shell to the path
+ IBuildEnvironmentVariable path = new IBuildEnvironmentVariable() {
+ public String getName() {
+ return "PATH"; //$NON-NLS-1$
+ }
+
+ public String getValue() {
+ // I'm giving MSYS precedence over Cygwin. I'm biased that
+ // way :)
+ // TODO using the default paths for now, need smarter ways
+ // to get at them
+ // Alternatively the user can add the bin to their path
+ // themselves.
+ File bin = new File("C:\\MinGW\\msys\\1.0\\bin"); //$NON-NLS-1$
+ if (bin.isDirectory()) {
+ return bin.getAbsolutePath();
+ }
+
+ bin = new File("C:\\cygwin\\bin"); //$NON-NLS-1$
+ if (bin.isDirectory())
+ return bin.getAbsolutePath();
+
+ return null;
+ }
+
+ public int getOperation() {
+ return ENVVAR_PREPEND;
+ }
+
+ public String getDelimiter() {
+ return ";"; //$NON-NLS-1$
+ }
+ };
+ if (path.getValue() != null)
+ mEnvVars.put(path.getName(), path);
+
+ // Since we're using real paths, need to tell cygwin it's OK
+ IBuildEnvironmentVariable cygwin = new IBuildEnvironmentVariable() {
+ public String getName() {
+ return "CYGWIN"; //$NON-NLS-1$
+ }
+
+ public String getValue() {
+ return "nodosfilewarning"; //$NON-NLS-1$
+ }
+
+ public int getOperation() {
+ return ENVVAR_REPLACE;
+ }
+
+ public String getDelimiter() {
+ return null;
+ }
+ };
+
+ mEnvVars.put(cygwin.getName(), cygwin);
+ }
+ }
+
+ public IBuildEnvironmentVariable getVariable(String variableName,
+ IConfiguration configuration, IEnvironmentVariableProvider provider) {
+ init();
+ return mEnvVars.get(variableName);
+ }
+
+ public IBuildEnvironmentVariable[] getVariables(
+ IConfiguration configuration, IEnvironmentVariableProvider provider) {
+ init();
+ return mEnvVars.values().toArray(new IBuildEnvironmentVariable[mEnvVars.size()]);
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveredPathInfo.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveredPathInfo.java
new file mode 100644
index 0000000..7baeb63
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveredPathInfo.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.discovery;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class NdkDiscoveredPathInfo implements IDiscoveredPathInfo {
+
+ private final IProject mProject;
+ private long mLastUpdate = IFile.NULL_STAMP;
+ private IPath[] mIncludePaths;
+ private Map<String, String> mSymbols;
+ private boolean mNeedReindexing = false;
+ private static final IPath ANDROID_MK = new Path("jni/Android.mk");
+
+ // Keys for preferences
+ public static final String LAST_UPDATE = "lastUpdate"; //$NON-NLS-1$
+
+ public NdkDiscoveredPathInfo(IProject project) {
+ this.mProject = project;
+ load();
+ }
+
+ public IProject getProject() {
+ return mProject;
+ }
+
+ public IPath[] getIncludePaths() {
+ if (mNeedReindexing) {
+ // Call for a reindex
+ // TODO this is probably a bug. a new include path should trigger
+ // reindexing anyway, no?
+ // BTW, can't do this in the update since the indexer runs before
+ // this gets called
+ CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(mProject));
+ mNeedReindexing = false;
+ }
+ return mIncludePaths;
+ }
+
+ void setIncludePaths(List<String> pathStrings) {
+ mIncludePaths = new IPath[pathStrings.size()];
+ int i = 0;
+ for (String path : pathStrings)
+ mIncludePaths[i++] = new Path(path);
+ mNeedReindexing = true;
+ }
+
+ public Map<String, String> getSymbols() {
+ if (mSymbols == null)
+ mSymbols = new HashMap<String, String>();
+ return mSymbols;
+ }
+
+ void setSymbols(Map<String, String> symbols) {
+ this.mSymbols = symbols;
+ }
+
+ public IDiscoveredScannerInfoSerializable getSerializable() {
+ return null;
+ }
+
+ public void update(IProgressMonitor monitor) throws CoreException {
+ if (!needUpdating())
+ return;
+
+ new NdkDiscoveryUpdater(this).runUpdate(monitor);
+
+ if (mIncludePaths != null && mSymbols != null) {
+ recordUpdate();
+ save();
+ }
+ }
+
+ private boolean needUpdating() {
+ if (mLastUpdate == IFile.NULL_STAMP)
+ return true;
+ return mProject.getFile(ANDROID_MK).getLocalTimeStamp() > mLastUpdate; //$NON-NLS-1$
+ }
+
+ private void recordUpdate() {
+ mLastUpdate = mProject.getFile(ANDROID_MK).getLocalTimeStamp(); //$NON-NLS-1$
+ }
+
+ public void delete() {
+ mLastUpdate = IFile.NULL_STAMP;
+ }
+
+ private File getInfoFile() {
+ File stateLoc = Activator.getDefault().getStateLocation().toFile();
+ return new File(stateLoc, mProject.getName() + ".pathInfo"); //$NON-NLS-1$
+ }
+
+ private void save() {
+ try {
+ File infoFile = getInfoFile();
+ infoFile.getParentFile().mkdirs();
+ PrintStream out = new PrintStream(infoFile);
+
+ // timestamp
+ out.print("t,"); //$NON-NLS-1$
+ out.print(mLastUpdate);
+ out.println();
+
+ for (IPath include : mIncludePaths) {
+ out.print("i,"); //$NON-NLS-1$
+ out.print(include.toPortableString());
+ out.println();
+ }
+
+ for (Entry<String, String> symbol : mSymbols.entrySet()) {
+ out.print("d,"); //$NON-NLS-1$
+ out.print(symbol.getKey());
+ out.print(","); //$NON-NLS-1$
+ out.print(symbol.getValue());
+ out.println();
+ }
+
+ out.close();
+ } catch (IOException e) {
+ Activator.log(e);
+ }
+
+ }
+
+ private void load() {
+ try {
+ File infoFile = getInfoFile();
+ if (!infoFile.exists())
+ return;
+
+ long timestamp = IFile.NULL_STAMP;
+ List<IPath> includes = new ArrayList<IPath>();
+ Map<String, String> defines = new HashMap<String, String>();
+
+ BufferedReader reader = new BufferedReader(new FileReader(infoFile));
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+ switch (line.charAt(0)) {
+ case 't':
+ timestamp = Long.valueOf(line.substring(2));
+ break;
+ case 'i':
+ includes.add(Path.fromPortableString(line.substring(2)));
+ break;
+ case 'd':
+ int n = line.indexOf(',', 2);
+ if (n == -1)
+ defines.put(line.substring(2), ""); //$NON-NLS-1$
+ else
+ defines.put(line.substring(2, n), line.substring(n + 1));
+ break;
+ }
+ }
+ reader.close();
+
+ mLastUpdate = timestamp;
+ mIncludePaths = includes.toArray(new IPath[includes.size()]);
+ mSymbols = defines;
+ } catch (IOException e) {
+ Activator.log(e);
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveryUpdater.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveryUpdater.java
new file mode 100644
index 0000000..2a84cdb
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkDiscoveryUpdater.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.discovery;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+import com.android.ide.eclipse.adt.ndk.internal.build.NdkCommandLauncher;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.managedbuilder.core.IBuilder;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class NdkDiscoveryUpdater {
+
+ private final NdkDiscoveredPathInfo mPathInfo;
+ private final IProject mProject;
+
+ private boolean mCPlusPlus = false;
+ private String mCommand;
+ private List<String> mArguments = new ArrayList<String>();
+
+ public NdkDiscoveryUpdater(NdkDiscoveredPathInfo pathInfo) {
+ mPathInfo = pathInfo;
+ mProject = pathInfo.getProject();
+ }
+
+ public void runUpdate(IProgressMonitor monitor) throws CoreException {
+ try {
+ // Run ndk-build -nB to get the list of commands
+ IPath commandPath = new Path("ndk-build"); //$NON-NLS-1$
+ String[] args = {
+ "-nB"}; //$NON-NLS-1$
+ String[] env = calcEnvironment();
+ File projectDir = new File(mProject.getLocationURI());
+ IPath changeToDirectory = new Path(projectDir.getAbsolutePath());
+ Process proc = new NdkCommandLauncher().execute(commandPath, args, env,
+ changeToDirectory, monitor);
+ if (proc == null)
+ // proc failed to start
+ return;
+ BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+ String line = reader.readLine();
+ while (line != null) {
+ checkBuildLine(line);
+ line = reader.readLine();
+ }
+
+ if (mCommand == null)
+ return;
+
+ // Run the unique commands with special gcc options to extract the
+ // symbols and paths
+ // -E -P -v -dD
+ mArguments.add("-E"); //$NON-NLS-1$
+ mArguments.add("-P"); //$NON-NLS-1$
+ mArguments.add("-v"); //$NON-NLS-1$
+ mArguments.add("-dD"); //$NON-NLS-1$
+
+ URL url = Activator.findFile(new Path(
+ "discovery/" + (mCPlusPlus ? "test.cpp" : "test.c"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ File testFile = new File(FileLocator.toFileURL(url).toURI());
+ String testFileName = testFile.getAbsolutePath().replace('\\', '/');
+ mArguments.add(testFileName);
+
+ args = mArguments.toArray(new String[mArguments.size()]);
+ proc = new NdkCommandLauncher().execute(new Path(mCommand), args, env,
+ changeToDirectory, monitor);
+ // Error stream has the includes
+ final InputStream errStream = proc.getErrorStream();
+ new Thread() {
+ @Override
+ public void run() {
+ checkIncludes(errStream);
+ };
+ }.start();
+
+ // Input stream has the defines
+ checkDefines(proc.getInputStream());
+ } catch (IOException e) {
+ throw new CoreException(Activator.newStatus(e));
+ } catch (URISyntaxException e) {
+ throw new CoreException(Activator.newStatus(e));
+ }
+ }
+
+ private String[] calcEnvironment() throws CoreException {
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(mProject);
+ IBuilder builder = info.getDefaultConfiguration().getBuilder();
+ HashMap<String, String> envMap = new HashMap<String, String>();
+ if (builder.appendEnvironment()) {
+ ICConfigurationDescription cfgDes = ManagedBuildManager
+ .getDescriptionForConfiguration(builder.getParent().getParent());
+ IEnvironmentVariableManager mngr = CCorePlugin.getDefault()
+ .getBuildEnvironmentManager();
+ IEnvironmentVariable[] vars = mngr.getVariables(cfgDes, true);
+ for (IEnvironmentVariable var : vars) {
+ envMap.put(var.getName(), var.getValue());
+ }
+ }
+ // Add variables from build info
+ @SuppressWarnings("unchecked")
+ Map<String, String> builderEnv = builder.getExpandedEnvironment();
+ if (builderEnv != null)
+ envMap.putAll(builderEnv);
+ List<String> strings = new ArrayList<String>(envMap.size());
+ for (Entry<String, String> entry : envMap.entrySet()) {
+ StringBuffer buffer = new StringBuffer(entry.getKey());
+ buffer.append('=').append(entry.getValue());
+ strings.add(buffer.toString());
+ }
+ return strings.toArray(new String[strings.size()]);
+ }
+
+ private static class Line {
+ private final String line;
+ private int pos;
+
+ public Line(String line) {
+ this.line = line;
+ }
+
+ public Line(String line, int pos) {
+ this(line);
+ this.pos = pos;
+ }
+
+ public String getToken() {
+ skipWhiteSpace();
+ if (pos == line.length())
+ return null;
+
+ int start = pos;
+ boolean inQuote = false;
+
+ while (true) {
+ char c = line.charAt(pos);
+ if (c == ' ') {
+ if (!inQuote)
+ return line.substring(start, pos);
+ } else if (c == '"') {
+ inQuote = !inQuote;
+ }
+
+ if (++pos == line.length())
+ return null;
+ }
+
+ }
+
+ private String getRemaining() {
+ if (pos == line.length())
+ return null;
+
+ skipWhiteSpace();
+ String rc = line.substring(pos);
+ pos = line.length();
+ return rc;
+ }
+
+ private void skipWhiteSpace() {
+ while (true) {
+ if (pos == line.length())
+ return;
+ char c = line.charAt(pos);
+ if (c == ' ')
+ pos++;
+ else
+ return;
+ }
+ }
+ }
+
+ private void checkBuildLine(String text) {
+ Line line = new Line(text);
+ String cmd = line.getToken();
+ if (cmd == null) {
+ return;
+ } else if (cmd.endsWith("g++")) { //$NON-NLS-1$
+ if (mCommand == null || !mCPlusPlus) {
+ mCommand = cmd;
+ mCPlusPlus = true;
+ }
+ gatherOptions(line);
+ } else if (cmd.endsWith("gcc")) { //$NON-NLS-1$
+ if (mCommand == null)
+ mCommand = cmd;
+ gatherOptions(line);
+ }
+ }
+
+ private void gatherOptions(Line line) {
+ for (String option = line.getToken(); option != null; option = line.getToken()) {
+ if (option.startsWith("-")) { //$NON-NLS-1$
+ // only look at options
+ if (option.equals("-I")) { //$NON-NLS-1$
+ String dir = line.getToken();
+ if (dir != null)
+ addArg(option + dir);
+ } else if (option.startsWith("-I")) { //$NON-NLS-1$
+ addArg(option);
+ } else if (option.equals("-D")) { //$NON-NLS-1$
+ String def = line.getToken();
+ if (def != null)
+ addArg(option + def);
+ } else if (option.startsWith("-D")) { //$NON-NLS-1$
+ addArg(option);
+ } else if (option.startsWith("-f")) { //$NON-NLS-1$
+ addArg(option);
+ } else if (option.startsWith("-m")) { //$NON-NLS-1$
+ addArg(option);
+ } else if (option.startsWith("--sysroot")) { //$NON-NLS-1$
+ addArg(option);
+ }
+ }
+ }
+ }
+
+ private void addArg(String arg) {
+ if (!mArguments.contains(arg))
+ mArguments.add(arg);
+ }
+
+ private void checkIncludes(InputStream in) {
+ try {
+ List<String> includes = new ArrayList<String>();
+ boolean inIncludes1 = false;
+ boolean inIncludes2 = false;
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line = reader.readLine();
+ while (line != null) {
+ if (!inIncludes1) {
+ if (line.equals("#include \"...\" search starts here:")) //$NON-NLS-1$
+ inIncludes1 = true;
+ } else {
+ if (!inIncludes2) {
+ if (line.equals("#include <...> search starts here:")) //$NON-NLS-1$
+ inIncludes2 = true;
+ else
+ includes.add(line.trim());
+ } else {
+ if (line.equals("End of search list.")) { //$NON-NLS-1$
+ mPathInfo.setIncludePaths(includes);
+ } else {
+ includes.add(line.trim());
+ }
+ }
+ }
+ line = reader.readLine();
+ }
+ } catch (IOException e) {
+ Activator.log(e);
+ }
+ }
+
+ private void checkDefines(InputStream in) {
+ try {
+ Map<String, String> defines = new HashMap<String, String>();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line = reader.readLine();
+ while (line != null) {
+ if (line.startsWith("#define")) { //$NON-NLS-1$
+ Line l = new Line(line, 7);
+ String var = l.getToken();
+ if (var == null)
+ continue;
+ String value = l.getRemaining();
+ if (value == null)
+ value = ""; //$NON-NLS-1$
+ defines.put(var, value);
+ }
+ line = reader.readLine();
+ }
+ mPathInfo.setSymbols(defines);
+ } catch (IOException e) {
+ Activator.log(e);
+ }
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkScannerInfoCollector.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkScannerInfoCollector.java
new file mode 100644
index 0000000..1538948
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/discovery/NdkScannerInfoCollector.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.discovery;
+
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector3;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import java.util.List;
+import java.util.Map;
+
+public class NdkScannerInfoCollector implements IScannerInfoCollector3,
+ IScannerInfoCollectorCleaner, IManagedScannerInfoCollector {
+
+ private NdkDiscoveredPathInfo mPathInfo;
+
+ public void contributeToScannerConfig(Object resource, @SuppressWarnings("rawtypes")
+ Map scannerInfo) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public @SuppressWarnings("rawtypes")
+ List getCollectedScannerInfo(Object resource, ScannerInfoTypes type) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void setProject(IProject project) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException {
+ mPathInfo.update(monitor);
+ }
+
+ public IDiscoveredPathInfo createPathInfoObject() {
+ return mPathInfo;
+ }
+
+ public Map<String, String> getDefinedSymbols() {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public @SuppressWarnings("rawtypes")
+ List getIncludePaths() {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void setInfoContext(InfoContext context) {
+ mPathInfo = new NdkDiscoveredPathInfo(context.getProject());
+ }
+
+ public void deleteAllPaths(IResource resource) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void deleteAllSymbols(IResource resource) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void deletePath(IResource resource, String path) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void deleteSymbol(IResource resource, String symbol) {
+ throw new Error("Not implemented"); //$NON-NLS-1$
+ }
+
+ public void deleteAll(IResource resource) {
+ mPathInfo.delete();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/messages.properties b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/messages.properties
new file mode 100644
index 0000000..63400ff
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/messages.properties
@@ -0,0 +1,16 @@
+AddNativeWizardPage_Description=Settings for generated native components for project.
+AddNativeWizardPage_LibraryName=Library Name:
+AddNativeWizardPage_Location_not_valid=NDK location not valid in preferences.
+AddNativeWizardPage_Title=Add Android Native Support
+NDKPreferencePage_Location=NDK Location
+NDKPreferencePage_not_a_valid_directory=Not a valid directory
+NDKPreferencePage_not_a_valid_NDK_directory=Not a valid NDK directory
+NDKPreferencePage_Preferences=Android NDK Preferences
+SetFolders_Missing_project_name=Missing project name
+SetFolders_No_folders=No folders
+SetFolders_Project_does_not_exist=Project does not exist
+SimpleFile_Bad_file_operation=bad file operation
+SimpleFile_Bundle_not_found=bundle not found
+SimpleFile_Could_not_fine_source=could not find source file:
+SimpleFile_No_project_name=no project name
+SimpleFile_Project_does_not_exist=project does not exist
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferenceInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferenceInitializer.java
new file mode 100644
index 0000000..cd16691
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferenceInitializer.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.preferences;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+import com.android.ide.eclipse.adt.ndk.internal.NdkManager;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+public class NdkPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+
+ store.setDefault(NdkManager.NDK_LOCATION, ""); //$NON-NLS-1$
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferencePage.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferencePage.java
new file mode 100644
index 0000000..55989e7
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/preferences/NdkPreferencePage.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.preferences;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+import com.android.ide.eclipse.adt.ndk.internal.Messages;
+import com.android.ide.eclipse.adt.ndk.internal.NdkManager;
+
+import org.eclipse.jface.preference.DirectoryFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class NdkPreferencePage extends FieldEditorPreferencePage implements
+ IWorkbenchPreferencePage {
+
+ private NdkDirectoryFieldEditor mNdkDirectoryEditor;
+
+ public NdkPreferencePage() {
+ super(GRID);
+ setPreferenceStore(Activator.getDefault().getPreferenceStore());
+ setDescription(Messages.NDKPreferencePage_Preferences);
+ }
+
+ @Override
+ protected void createFieldEditors() {
+ mNdkDirectoryEditor = new NdkDirectoryFieldEditor(NdkManager.NDK_LOCATION,
+ Messages.NDKPreferencePage_Location, getFieldEditorParent());
+ addField(mNdkDirectoryEditor);
+ }
+
+ private static class NdkDirectoryFieldEditor extends DirectoryFieldEditor {
+ public NdkDirectoryFieldEditor(String name, String labelText, Composite parent) {
+ super(name, labelText, parent);
+ setEmptyStringAllowed(false);
+ }
+
+ @Override
+ protected boolean doCheckState() {
+ if (!super.doCheckState()) {
+ setErrorMessage(Messages.NDKPreferencePage_not_a_valid_directory);
+ return false;
+ }
+
+ String dirname = getTextControl().getText().trim();
+ if (!NdkManager.isValidNdkLocation(dirname)) {
+ setErrorMessage(Messages.NDKPreferencePage_not_a_valid_NDK_directory);
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public Text getTextControl(Composite parent) {
+ setValidateStrategy(VALIDATE_ON_KEY_STROKE);
+ return super.getTextControl(parent);
+ }
+
+ }
+
+ public void init(IWorkbench workbench) {
+ // Nothing to do herea
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+
+ if (mNdkDirectoryEditor != null) {
+ mNdkDirectoryEditor.dispose();
+ mNdkDirectoryEditor = null;
+ }
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SetFolders.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SetFolders.java
new file mode 100644
index 0000000..26c1c5b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SetFolders.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.templates;
+
+import com.android.ide.eclipse.adt.ndk.internal.Messages;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.core.templateengine.TemplateCore;
+import org.eclipse.cdt.core.templateengine.process.ProcessArgument;
+import org.eclipse.cdt.core.templateengine.process.ProcessFailureException;
+import org.eclipse.cdt.core.templateengine.process.ProcessRunner;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SetFolders extends ProcessRunner {
+
+ @Override
+ public void process(TemplateCore template, ProcessArgument[] args, String processId,
+ IProgressMonitor monitor)
+ throws ProcessFailureException {
+ String projectName = null;
+ String[] sourceFolders = null;
+ String[] outputFolders = null;
+
+ for (ProcessArgument arg : args) {
+ String argName = arg.getName();
+ if (argName.equals("projectName")) { //$NON-NLS-1$
+ projectName = arg.getSimpleValue();
+ } else if (argName.equals("sourceFolders")) { //$NON-NLS-1$
+ sourceFolders = arg.getSimpleArrayValue();
+ } else if (argName.equals("outputFolders")) { //$NON-NLS-1$
+ outputFolders = arg.getSimpleArrayValue();
+ }
+ }
+
+ // Get the project
+ if (projectName == null)
+ throw new ProcessFailureException(Messages.SetFolders_Missing_project_name);
+
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ if (!project.exists())
+ throw new ProcessFailureException(Messages.SetFolders_Project_does_not_exist);
+
+ // Create the folders
+ if (sourceFolders == null && outputFolders == null)
+ throw new ProcessFailureException(Messages.SetFolders_No_folders);
+
+ try {
+ // Add them in
+ ICProject cproject = CCorePlugin.getDefault().getCoreModel().create(project);
+ IPathEntry[] pathEntries = cproject.getRawPathEntries();
+ List<IPathEntry> newEntries = new ArrayList<IPathEntry>(pathEntries.length);
+ for (IPathEntry pathEntry : pathEntries) {
+ // remove the old source and output entries
+ if (pathEntry.getEntryKind() != IPathEntry.CDT_SOURCE
+ && pathEntry.getEntryKind() != IPathEntry.CDT_OUTPUT) {
+ newEntries.add(pathEntry);
+ }
+ }
+ if (sourceFolders != null)
+ for (String sourceFolder : sourceFolders) {
+ IFolder folder = project.getFolder(new Path(sourceFolder));
+ if (!folder.exists())
+ folder.create(true, true, monitor);
+ newEntries.add(CoreModel.newSourceEntry(folder.getFullPath()));
+ }
+ if (outputFolders != null)
+ for (String outputFolder : outputFolders) {
+ IFolder folder = project.getFolder(new Path(outputFolder));
+ if (!folder.exists())
+ folder.create(true, true, monitor);
+ newEntries.add(CoreModel.newOutputEntry(folder.getFullPath()));
+ }
+ cproject.setRawPathEntries(newEntries.toArray(new IPathEntry[newEntries.size()]),
+ monitor);
+ } catch (CoreException e) {
+ throw new ProcessFailureException(e);
+ }
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SimpleFile.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SimpleFile.java
new file mode 100644
index 0000000..874ba22
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/SimpleFile.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.templates;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+import com.android.ide.eclipse.adt.ndk.internal.Messages;
+
+import org.eclipse.cdt.core.templateengine.TemplateCore;
+import org.eclipse.cdt.core.templateengine.process.ProcessArgument;
+import org.eclipse.cdt.core.templateengine.process.ProcessFailureException;
+import org.eclipse.cdt.core.templateengine.process.ProcessRunner;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.osgi.framework.Bundle;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SimpleFile extends ProcessRunner {
+
+ private static final class FileOp {
+ public String source;
+ public String destination;
+ }
+
+ @Override
+ public void process(TemplateCore template, ProcessArgument[] args, String processId,
+ IProgressMonitor monitor)
+ throws ProcessFailureException {
+
+ // Fetch the args
+ String projectName = null;
+ List<FileOp> fileOps = new ArrayList<FileOp>();
+
+ for (ProcessArgument arg : args) {
+ if (arg.getName().equals("projectName")) //$NON-NLS-1$
+ projectName = arg.getSimpleValue();
+ else if (arg.getName().equals("files")) { //$NON-NLS-1$
+ ProcessArgument[][] files = arg.getComplexArrayValue();
+ for (ProcessArgument[] file : files) {
+ FileOp op = new FileOp();
+ for (ProcessArgument fileArg : file) {
+ if (fileArg.getName().equals("source")) //$NON-NLS-1$
+ op.source = fileArg.getSimpleValue();
+ else if (fileArg.getName().equals("destination")) //$NON-NLS-1$
+ op.destination = fileArg.getSimpleValue();
+ }
+ if (op.source == null || op.destination == null)
+ throw new ProcessFailureException(Messages.SimpleFile_Bad_file_operation);
+ fileOps.add(op);
+ }
+ }
+ }
+
+ if (projectName == null)
+ throw new ProcessFailureException(Messages.SimpleFile_No_project_name);
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ if (!project.exists())
+ throw new ProcessFailureException(Messages.SimpleFile_Project_does_not_exist);
+
+ // Find bundle to find source files
+ Bundle bundle = Activator.getBundle(template.getTemplateInfo().getPluginId());
+ if (bundle == null)
+ throw new ProcessFailureException(Messages.SimpleFile_Bundle_not_found);
+
+ try {
+ for (FileOp op : fileOps) {
+ IFile destFile = project.getFile(new Path(op.destination));
+ if (destFile.exists())
+ // don't overwrite files if they exist already
+ continue;
+
+ // Make sure parent folders are created
+ mkDirs(project, destFile.getParent(), monitor);
+
+ URL sourceURL = FileLocator.find(bundle, new Path(op.source), null);
+ if (sourceURL == null)
+ throw new ProcessFailureException(Messages.SimpleFile_Could_not_fine_source
+ + op.source);
+
+ TemplatedInputStream in = new TemplatedInputStream(sourceURL.openStream(),
+ template.getValueStore());
+ destFile.create(in, true, monitor);
+ in.close();
+ }
+ } catch (IOException e) {
+ throw new ProcessFailureException(e);
+ } catch (CoreException e) {
+ throw new ProcessFailureException(e);
+ }
+
+ }
+
+ private void mkDirs(IProject project, IContainer container, IProgressMonitor monitor)
+ throws CoreException {
+ if (container.exists())
+ return;
+ mkDirs(project, container.getParent(), monitor);
+ ((IFolder) container).create(true, true, monitor);
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/TemplatedInputStream.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/TemplatedInputStream.java
new file mode 100644
index 0000000..241f954
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/templates/TemplatedInputStream.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.templates;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * Reads from a template substituting marked values from the supplied Map.
+ */
+public class TemplatedInputStream extends InputStream {
+
+ private final InputStream mIn;
+ private final Map<String, String> mMap;
+ private char[] mSub;
+ private int mPos;
+ private int mMark;
+
+ public TemplatedInputStream(InputStream in, Map<String, String> map) {
+ this.mIn = in;
+ this.mMap = map;
+ }
+
+ @Override
+ public int read() throws IOException {
+ // if from a mark, return the char
+ if (mMark != 0) {
+ int c = mMark;
+ mMark = 0;
+ return c;
+ }
+
+ // return char from sub layer if available
+ if (mSub != null) {
+ char c = mSub[mPos++];
+ if (mPos >= mSub.length)
+ mSub = null;
+ return c;
+ }
+
+ int c = mIn.read();
+ if (c == '%') {
+ // check if it's a sub
+ c = mIn.read();
+ if (c == '{') {
+ // it's a sub
+ StringBuffer buff = new StringBuffer();
+ for (c = mIn.read(); c != '}' && c >= 0; c = mIn.read())
+ buff.append((char) c);
+ String str = mMap.get(buff.toString());
+ if (str != null) {
+ mSub = str.toCharArray();
+ mPos = 0;
+ }
+ return read(); // recurse to get the real char
+ } else {
+ // not a sub
+ mMark = c;
+ return '%';
+ }
+ }
+
+ return c;
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ mIn.close();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizard.java
new file mode 100644
index 0000000..8f66336
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizard.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.wizards;
+
+import com.android.ide.eclipse.adt.ndk.internal.Activator;
+import com.android.ide.eclipse.adt.ndk.internal.NdkManager;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.WorkbenchException;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AddNativeWizard extends Wizard {
+
+ private final IProject mProject;
+ private final IWorkbenchWindow mWindow;
+
+ private AddNativeWizardPage mAddNativeWizardPage;
+ private Map<String, String> mTemplateArgs = new HashMap<String, String>();
+
+ public AddNativeWizard(IProject project, IWorkbenchWindow window) {
+ mProject = project;
+ mWindow = window;
+ mTemplateArgs.put(NdkManager.LIBRARY_NAME, project.getName());
+ }
+
+ @Override
+ public void addPages() {
+ mAddNativeWizardPage = new AddNativeWizardPage(mTemplateArgs);
+ addPage(mAddNativeWizardPage);
+ }
+
+ @Override
+ public boolean performFinish() {
+ // Switch to C/C++ Perspective
+ try {
+ mWindow.getWorkbench().showPerspective(CUIPlugin.ID_CPERSPECTIVE, mWindow);
+ } catch (WorkbenchException e1) {
+ Activator.log(e1);
+ }
+
+ mAddNativeWizardPage.updateArgs(mTemplateArgs);
+
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ IWorkspaceRunnable op1 = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor1) throws CoreException {
+ // Convert to CDT project
+ CCorePlugin.getDefault().convertProjectToCC(mProject, monitor1,
+ MakeCorePlugin.MAKE_PROJECT_ID);
+ // Set up build information
+ new NdkWizardHandler().convertProject(mProject, monitor1);
+ // Run the template
+ NdkManager.addNativeSupport(mProject, mTemplateArgs, monitor1);
+ }
+ };
+ // TODO run from a job
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ try {
+ workspace.run(op1, workspace.getRoot(), 0, new NullProgressMonitor());
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ };
+ try {
+ getContainer().run(false, true, op);
+ return true;
+ } catch (InterruptedException e) {
+ Activator.log(e);
+ return false;
+ } catch (InvocationTargetException e) {
+ Activator.log(e);
+ return false;
+ }
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizardPage.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizardPage.java
new file mode 100644
index 0000000..4c00aef
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/AddNativeWizardPage.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.wizards;
+
+import com.android.ide.eclipse.adt.ndk.internal.Messages;
+import com.android.ide.eclipse.adt.ndk.internal.NdkManager;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.Map;
+
+public class AddNativeWizardPage extends WizardPage {
+
+ private final String defaultLibraryName;
+
+ private Text libraryNameText;
+
+ public AddNativeWizardPage(Map<String, String> templateArgs) {
+ super("addNativeWizardPage"); //$NON-NLS-1$
+ setDescription(Messages.AddNativeWizardPage_Description);
+ setTitle(Messages.AddNativeWizardPage_Title);
+
+ defaultLibraryName = templateArgs.get(NdkManager.LIBRARY_NAME);
+ if (!NdkManager.isNdkLocationValid()) {
+ setErrorMessage(Messages.AddNativeWizardPage_Location_not_valid);
+ }
+ }
+
+ @Override
+ public boolean isPageComplete() {
+ return NdkManager.isNdkLocationValid();
+ }
+
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ setControl(container);
+ container.setLayout(new GridLayout(2, false));
+
+ Label lblLibraryName = new Label(container, SWT.NONE);
+ lblLibraryName.setText(Messages.AddNativeWizardPage_LibraryName);
+
+ Composite composite = new Composite(container, SWT.NONE);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ composite.setLayout(new GridLayout(3, false));
+
+ Label lblLib = new Label(composite, SWT.NONE);
+ lblLib.setText("lib"); //$NON-NLS-1$
+
+ libraryNameText = new Text(composite, SWT.BORDER);
+ libraryNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ libraryNameText.setText(defaultLibraryName);
+
+ Label lblso = new Label(composite, SWT.NONE);
+ lblso.setText(".so"); //$NON-NLS-1$
+ }
+
+ public void updateArgs(Map<String, String> templateArgs) {
+ templateArgs.put(NdkManager.LIBRARY_NAME, libraryNameText.getText());
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/NdkWizardHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/NdkWizardHandler.java
new file mode 100644
index 0000000..152816a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/src/com/android/ide/eclipse/adt/ndk/internal/wizards/NdkWizardHandler.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.ndk.internal.wizards;
+
+import org.eclipse.cdt.managedbuilder.core.IToolChain;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.ui.wizards.STDWizardHandler;
+
+public class NdkWizardHandler extends STDWizardHandler {
+
+ public NdkWizardHandler() {
+ super(null, null);
+ }
+
+ @Override
+ public IToolChain[] getSelectedToolChains() {
+ IToolChain[] tcs = ManagedBuildManager.getRealToolChains();
+ for (IToolChain tc : tcs) {
+ if (tc.getId().equals("com.android.toolchain.gcc")) //$NON-NLS-1$
+ return new IToolChain[] {
+ tc
+ };
+ }
+ return super.getSelectedToolChains();
+ }
+
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/addNdkSupport.xml b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/addNdkSupport.xml
new file mode 100644
index 0000000..37c8814
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/addNdkSupport.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<template
+ type="ProjTempl"
+ version="1.0"
+ revision="1.0"
+ id="AddNdkSupport"
+ label="Add Android NDK Support"
+ description="Adds NDK support to Android Java projects"
+ help="help.html">
+ <process type="com.android.ide.eclipse.adt.ndk.SetFolders">
+ <simple name="projectName" value="$(projectName)"/>
+ <simple-array name="sourceFolders">
+ <element value="jni"/>
+ </simple-array>
+ <simple-array name="outputFolders">
+ <element value="obj"/>
+ <element value="libs"/>
+ </simple-array>
+ </process>
+ <process type="com.android.ide.eclipse.adt.ndk.SimpleFile">
+ <simple name="projectName" value="$(projectName)"/>
+ <complex-array name="files">
+ <element>
+ <simple name="source" value="templates/resources/tAndroid.mk"/>
+ <simple name="destination" value="jni/Android.mk"/>
+ </element>
+ <element>
+ <simple name="source" value="templates/resources/main.cpp"/>
+ <simple name="destination" value="jni/$(libraryName).cpp"/>
+ </element>
+ </complex-array>
+ </process>
+</template>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/main.cpp b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/main.cpp
new file mode 100644
index 0000000..6434c66
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/main.cpp
@@ -0,0 +1 @@
+#include <jni.h>
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/tAndroid.mk b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/tAndroid.mk
new file mode 100644
index 0000000..cd9d479
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt.ndk/templates/resources/tAndroid.mk
@@ -0,0 +1,8 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := %{libraryName}
+LOCAL_SRC_FILES := %{libraryName}.cpp
+
+include $(BUILD_SHARED_LIBRARY)