1/******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17package com.badlogic.gdx.jnigen; 18 19import java.util.ArrayList; 20 21import com.badlogic.gdx.jnigen.BuildTarget.TargetOs; 22import com.badlogic.gdx.jnigen.FileDescriptor.FileType; 23 24public class AndroidNdkScriptGenerator { 25 public void generate (BuildConfig config, BuildTarget target) { 26 if (target.os != TargetOs.Android) throw new IllegalArgumentException("target os must be Android"); 27 28 // create all the directories for outputing object files, shared libs and natives jar as well as build scripts. 29 if (!config.libsDir.exists()) { 30 if (!config.libsDir.mkdirs()) 31 throw new RuntimeException("Couldn't create directory for shared library files in '" + config.libsDir + "'"); 32 } 33 if (!config.jniDir.exists()) { 34 if (!config.jniDir.mkdirs()) 35 throw new RuntimeException("Couldn't create native code directory '" + config.jniDir + "'"); 36 } 37 38 ArrayList<FileDescriptor> files = new ArrayList<FileDescriptor>(); 39 40 int idx = 0; 41 String[] includes = new String[target.cIncludes.length + target.cppIncludes.length]; 42 for (String include : target.cIncludes) 43 includes[idx++] = config.jniDir + "/" + include; 44 for (String include : target.cppIncludes) 45 includes[idx++] = config.jniDir + "/" + include; 46 47 idx = 0; 48 String[] excludes = new String[target.cExcludes.length + target.cppExcludes.length + 1]; 49 for (String exclude : target.cExcludes) 50 excludes[idx++] = config.jniDir + "/" + exclude; 51 for (String exclude : target.cppExcludes) 52 excludes[idx++] = config.jniDir + "/" + exclude; 53 excludes[idx] = "**/target/*"; 54 55 gatherSourceFiles(config.jniDir, includes, excludes, files); 56 57 // create Application.mk file 58 FileDescriptor application = config.jniDir.child("Application.mk"); 59 application.writeString(new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/Application.mk.template", 60 FileType.Classpath).readString(), false); 61 62 // create Android.mk file 63 String template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/Android.mk.template", FileType.Classpath) 64 .readString(); 65 66 StringBuffer srcFiles = new StringBuffer(); 67 for (int i = 0; i < files.size(); i++) { 68 if (i > 0) srcFiles.append("\t"); 69 srcFiles.append(files.get(i).path().replace('\\', '/').replace(config.jniDir.toString() + "/", "")); 70 if (i < files.size() - 1) 71 srcFiles.append("\\\n"); 72 else 73 srcFiles.append("\n"); 74 } 75 76 StringBuffer headerDirs = new StringBuffer(); 77 for (String headerDir : target.headerDirs) { 78 headerDirs.append(headerDir); 79 headerDirs.append(" "); 80 } 81 82 template = template.replace("%sharedLibName%", config.sharedLibName); 83 template = template.replace("%headerDirs%", headerDirs); 84 template = template.replace("%cFlags%", target.cFlags); 85 template = template.replace("%cppFlags%", target.cppFlags); 86 template = template.replace("%linkerFlags%", target.linkerFlags); 87 template = template.replace("%srcFiles%", srcFiles); 88 89 config.jniDir.child("Android.mk").writeString(template, false); 90 } 91 92 private void gatherSourceFiles (FileDescriptor file, String[] includes, String[] excludes, ArrayList<FileDescriptor> files) { 93 String fileName = file.path().replace('\\', '/'); 94 if (file.isDirectory()) { 95 if (match(fileName, excludes)) return; 96 for (FileDescriptor child : file.list()) { 97 gatherSourceFiles(child, includes, excludes, files); 98 } 99 } else { 100 if (match(fileName, includes) && !match(fileName, excludes)) files.add(file); 101 } 102 } 103 104 private boolean match (String file, String[] patterns) { 105 return new AntPathMatcher().match(file, patterns); 106 } 107} 108