Coverage Report - com.simpligility.maven.plugins.androidndk.AndroidNdk
 
Classes in this File Line Coverage Branch Coverage Complexity
AndroidNdk
10%
8/75
0%
0/50
7.429
 
 1  
 /*
 2  
  * Licensed under the Apache License, Version 2.0 (the "License");
 3  
  * you may not use this file except in compliance with the License.
 4  
  * You may obtain a copy of the License at
 5  
  *
 6  
  *      http://www.apache.org/licenses/LICENSE-2.0
 7  
  *
 8  
  * Unless required by applicable law or agreed to in writing, software
 9  
  * distributed under the License is distributed on an "AS IS" BASIS,
 10  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11  
  * See the License for the specific language governing permissions and
 12  
  * limitations under the License.
 13  
  */
 14  
 package com.simpligility.maven.plugins.androidndk;
 15  
 
 16  
 import com.simpligility.maven.plugins.androidndk.configuration.ArchitectureToolchainMappings;
 17  
 import com.simpligility.maven.plugins.androidndk.phase05compile.NdkBuildMojo;
 18  
 import org.apache.commons.lang3.SystemUtils;
 19  
 import org.apache.maven.plugin.MojoExecutionException;
 20  
 
 21  
 import java.io.File;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.List;
 25  
 
 26  
 /**
 27  
  * Represents an Android NDK.
 28  
  *
 29  
  * @author Johan Lindquist <johanlindquist@gmail.com>
 30  
  * @author Manfred Moser <manfred@simpligility.com>
 31  
  */
 32  
 public class AndroidNdk
 33  
 {
 34  
 
 35  
     public static final String PROPER_NDK_HOME_DIRECTORY_MESSAGE = "Please provide a proper Android NDK directory path as configuration parameter <ndk><path>...</path></ndk>"
 36  
             + " in the plugin <configuration/>. As an alternative, you may add the parameter to commandline: -Dandroid.ndk.path=... or set environment  variable "
 37  
             + NdkBuildMojo.ENV_ANDROID_NDK_HOME + ".";
 38  
 
 39  1
     public static final String[] NDK_ARCHITECTURES = { "arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64" };
 40  
 
 41  
     /**
 42  
      * Arm toolchain implementations.
 43  
      */
 44  1
     public static final String[] ARM_TOOLCHAIN = { "arm-linux-androideabi-4.9", "arm-linux-androideabi-4.8", "arm-linux-androideabi-4.7", "arm-linux-androideabi-4.6",
 45  
             "arm-linux-androideabi-4.4.3", "arm-linux-androidabi-clang3.5", "arm-linux-androidabi-clang3.6" };
 46  
 
 47  
     /**
 48  
      * ARM 64-bit toolchain implementations.
 49  
      */
 50  1
     public static final String[] ARM_64_TOOLCHAIN = { "aarch64-linux-android-4.9", "aarch64-linux-android-clang3.5", "aarch64-linux-android-clang3.6" };
 51  
 
 52  
     /**
 53  
      * x86 toolchain implementations.
 54  
      */
 55  1
     public static final String[] X86_TOOLCHAIN = { "x86-4.9", "x86-4.8", "x86-4.7", "x86-4.6", "x86-4.4.3", "x86-clang3.5", "x86-clang3.6" };
 56  
 
 57  
     /**
 58  
      * x86 64-bit toolchain implementations.
 59  
      */
 60  1
     public static final String[] X86_64_TOOLCHAIN = { "x86_64-4.9", "x86_64-clang3.5", "x86_64-clang3.6" };
 61  
 
 62  
     /**
 63  
      * Mips toolchain implementations.
 64  
      */
 65  1
     public static final String[] MIPS_TOOLCHAIN = { "mipsel-linux-android-4.9", "mipsel-linux-android-4.8", "mipsel-linux-android-4.7", "mipsel-linux-android-4.6", "mipsel-linux-android-4.4.3",
 66  
             "mipsel-linux-android-clang3.5", "mipsel-linux-android-clang3.6" };
 67  
 
 68  1
     public static final String[] MIPS_64_TOOLCHAIN = { "mips64el-linux-android-4.9", "mips64el-linux-android-clang3.5", "mips64el-linux-android-clang3.6" };
 69  
 
 70  
     /**
 71  
      * Possible locations for the gdbserver file.
 72  
      */
 73  1
     private static final String[] GDB_SERVER_LOCATIONS = { "toolchains/%s/prebuilt/gdbserver", "prebuilt/%s/gdbserver/gdbserver" };
 74  
 
 75  
     /**
 76  
      * Locations of toolchains
 77  
      */
 78  
     private static final String TOOLCHAIN_LOCATION = "toolchains/%s";
 79  
 
 80  
     private final File ndkPath;
 81  
 
 82  
     public AndroidNdk( File ndkPath )
 83  0
     {
 84  0
         assertPathIsDirectory( ndkPath );
 85  0
         this.ndkPath = ndkPath;
 86  0
     }
 87  
 
 88  
     private void assertPathIsDirectory( final File path )
 89  
     {
 90  0
         if ( path == null )
 91  
         {
 92  0
             throw new InvalidNdkException( PROPER_NDK_HOME_DIRECTORY_MESSAGE );
 93  
         }
 94  0
         if ( !path.isDirectory() )
 95  
         {
 96  0
             throw new InvalidNdkException(
 97  
                     "Path \"" + path + "\" is not a directory. " + PROPER_NDK_HOME_DIRECTORY_MESSAGE );
 98  
         }
 99  0
     }
 100  
 
 101  
     /**
 102  
      * Returns the complete path for the ndk-build tool, based on this NDK.
 103  
      *
 104  
      * @return the complete path as a <code>String</code>, including the tool's filename.
 105  
      */
 106  
     public String getNdkBuildPath()
 107  
     {
 108  0
         if ( SystemUtils.IS_OS_WINDOWS )
 109  
         {
 110  0
             return new File( ndkPath, "/ndk-build.cmd" ).getAbsolutePath();
 111  
         }
 112  
         else
 113  
         {
 114  0
             return new File( ndkPath, "/ndk-build" ).getAbsolutePath();
 115  
         }
 116  
     }
 117  
 
 118  
     public File getGdbServer( String ndkArchitecture ) throws MojoExecutionException
 119  
     {
 120  
         // create a list of possible gdb server parent folder locations
 121  0
         List<String> gdbServerLocations = new ArrayList<String>();
 122  0
         if ( ndkArchitecture.startsWith( "arm64-v8a" ) )
 123  
         {
 124  0
             gdbServerLocations.add( "android-arm64" );
 125  0
             gdbServerLocations.addAll( Arrays.asList( ARM_64_TOOLCHAIN ) );
 126  
         }
 127  0
         else if ( ndkArchitecture.startsWith( "arm" ) )
 128  
         {
 129  0
             gdbServerLocations.add( "android-arm" );
 130  0
             gdbServerLocations.addAll( Arrays.asList( ARM_TOOLCHAIN ) );
 131  
         }
 132  
         // x86_64 is before x86!
 133  0
         else if ( ndkArchitecture.startsWith( "x86_64" ) )
 134  
         {
 135  0
             gdbServerLocations.add( "android-x86_64" );
 136  0
             gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
 137  
         }
 138  0
         else if ( ndkArchitecture.startsWith( "x86" ) )
 139  
         {
 140  0
             gdbServerLocations.add( "android-x86" );
 141  0
             gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
 142  
         }
 143  0
         else if ( ndkArchitecture.startsWith( "mips" ) )
 144  
         {
 145  0
             gdbServerLocations.add( "android-mips" );
 146  0
             gdbServerLocations.addAll( Arrays.asList( MIPS_TOOLCHAIN ) );
 147  
         }
 148  
 
 149  
         // check for the gdb server
 150  0
         for ( String location : GDB_SERVER_LOCATIONS )
 151  
         {
 152  0
             for ( String gdbServerLocation : gdbServerLocations )
 153  
             {
 154  0
                 File gdbServerFile = new File( ndkPath, String.format( location, gdbServerLocation ) );
 155  0
                 if ( gdbServerFile.exists() )
 156  
                 {
 157  0
                     return gdbServerFile;
 158  
                 }
 159  0
             }
 160  
         }
 161  
 
 162  
         //  if we got here, throw an error
 163  0
         throw new MojoExecutionException( "gdbserver binary for architecture " + ndkArchitecture
 164  
                 + " does not exist, please double check the toolchain and OS used" );
 165  
     }
 166  
 
 167  
     /**
 168  
      * Retrieves, based on the architecture and possibly toolchain mappings, the toolchain for the architecture.
 169  
      * <br/>
 170  
      * <strong>Note:</strong> This method will return the <strong>default</strong> toolchain as defined by the NDK if
 171  
      * not specified in the <code>NDKArchitectureToolchainMappings</code>.
 172  
      *
 173  
      * @param ndkArchitecture                  Architecture to resolve toolchain for
 174  
      * @param architectureToolchainMappings User mappings of architecture to toolchain
 175  
      * @return Toolchain to be used for the architecture
 176  
      * @throws MojoExecutionException If a toolchain can not be resolved
 177  
      */
 178  
     public String getToolchainFromArchitecture( final String ndkArchitecture, final ArchitectureToolchainMappings architectureToolchainMappings ) throws MojoExecutionException
 179  
     {
 180  
         // arm64 is before arm!
 181  0
         if ( ndkArchitecture.startsWith( "arm64-v8a" ) )
 182  
         {
 183  0
             if ( architectureToolchainMappings != null )
 184  
             {
 185  0
                 return architectureToolchainMappings.getArm64 ();
 186  
             }
 187  0
             return findHighestSupportedToolchain( AndroidNdk.ARM_64_TOOLCHAIN );
 188  
         }
 189  0
         else if ( ndkArchitecture.startsWith( "arm" ) )
 190  
         {
 191  0
             if ( architectureToolchainMappings != null )
 192  
             {
 193  0
                 return architectureToolchainMappings.getArmeabi();
 194  
             }
 195  0
             return findHighestSupportedToolchain( AndroidNdk.ARM_TOOLCHAIN );
 196  
         }
 197  
         // x86_64 is before x86!
 198  0
         else if ( ndkArchitecture.startsWith( "x86_64" ) )
 199  
         {
 200  0
             if ( architectureToolchainMappings != null )
 201  
             {
 202  0
                 return architectureToolchainMappings.getX8664 ();
 203  
             }
 204  0
             return findHighestSupportedToolchain( AndroidNdk.X86_64_TOOLCHAIN );
 205  
         }
 206  0
         else if ( ndkArchitecture.startsWith( "x86" ) )
 207  
         {
 208  0
             if ( architectureToolchainMappings != null )
 209  
             {
 210  0
                 return architectureToolchainMappings.getX86();
 211  
             }
 212  0
             return findHighestSupportedToolchain( AndroidNdk.X86_TOOLCHAIN );
 213  
         }
 214  0
         else if ( ndkArchitecture.startsWith( "mips" ) )
 215  
         {
 216  0
             if ( architectureToolchainMappings != null )
 217  
             {
 218  0
                 return architectureToolchainMappings.getMips();
 219  
             }
 220  0
             return findHighestSupportedToolchain( AndroidNdk.MIPS_TOOLCHAIN );
 221  
         }
 222  
 
 223  
         //  if we got here, throw an error
 224  0
         throw new MojoExecutionException( "Toolchain for architecture " + ndkArchitecture + " does not exist, please double check the setup" );
 225  
     }
 226  
 
 227  
     public static void validateToolchainDirectory( File toolchainDirectory ) throws MojoExecutionException
 228  
     {
 229  0
         if ( !toolchainDirectory.exists() )
 230  
         {
 231  
             //  if we got here, throw an error
 232  0
             throw new MojoExecutionException( "Toolchain directory " + toolchainDirectory + " does not exist" );
 233  
         }
 234  0
         if ( !toolchainDirectory.canRead() )
 235  
         {
 236  
             //  if we got here, throw an error
 237  0
             throw new MojoExecutionException( "Toolchain directory " + toolchainDirectory + " exist but can not be read" );
 238  
         }
 239  0
     }
 240  
 
 241  
     private String findHighestSupportedToolchain( final String[] toolchains ) throws MojoExecutionException
 242  
     {
 243  0
         for ( String toolchain : toolchains )
 244  
         {
 245  0
             File toolchainDirectory = new File( ndkPath, String.format( TOOLCHAIN_LOCATION, toolchain ) );
 246  0
             if ( toolchainDirectory.exists() )
 247  
             {
 248  0
                 AndroidNdk.validateToolchainDirectory( toolchainDirectory );
 249  0
                 return toolchain;
 250  
             }
 251  
         }
 252  
 
 253  
         //  if we got here, throw an error
 254  0
         throw new MojoExecutionException( "No valid toolchain could be found in the " + ndkPath + "/toolchains directory" );
 255  
     }
 256  
 }
 257