package com.mobilesorcery.sdk.builder.winmobilecs;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import com.mobilesorcery.sdk.core.AbstractTool;
import com.mobilesorcery.sdk.core.CommandLineBuilder;
import com.mobilesorcery.sdk.core.DefaultPackager;
import com.mobilesorcery.sdk.core.IBuildConfiguration;
import com.mobilesorcery.sdk.core.IBuildResult;
import com.mobilesorcery.sdk.core.IBuildSession;
import com.mobilesorcery.sdk.core.IBuildVariant;
import com.mobilesorcery.sdk.core.IFileTreeDiff;
import com.mobilesorcery.sdk.core.MoSyncBuilder;
import com.mobilesorcery.sdk.core.MoSyncProject;
import com.mobilesorcery.sdk.core.MoSyncTool;
import com.mobilesorcery.sdk.core.PackageToolPackager;
import com.mobilesorcery.sdk.core.ParameterResolverException;
import com.mobilesorcery.sdk.core.Util;
import com.mobilesorcery.sdk.profiles.IProfile;
public class WinMobileCSPackager extends PackageToolPackager {
public static final String ID = "com.mobilesorcery.sdk.build.winmobilecs.packager";
private static final String PROJECT_FILE = "project";
@Override
public void createPackage(MoSyncProject project, IBuildSession session,
IBuildVariant variant, IFileTreeDiff diff, IBuildResult buildResult)
throws CoreException {
DefaultPackager intern = new DefaultPackager(project, variant);
super.createPackage(project, session, variant, diff, buildResult);
// Notify user if we did not build the generated project and say why
if (!AbstractTool.isWindows()) {
intern.getConsole()
.addMessage(
"Visual Studio building only available in Windows, will not build generated project");
} else if (!shouldBuildWithVSPref(project) && !isEmulatorBuild(project, variant)) {
intern.getConsole()
.addMessage(
"Visual Studio building disabled, will not build generated project");
} else if (!MSBuild.getDefault().isValid()) {
intern.getConsole().addMessage("Visual Studio building disabled.");
intern.getConsole().addMessage("Could not find Visual Studio executable; see Preferences > MoSync Tool > Visual Studio (WP7)");
}
}
@Override
public Map<String, List<File>> computeBuildResult(MoSyncProject project,
IBuildVariant variant) {
DefaultPackager internal = new DefaultPackager(project, variant);
if (shouldBuildWithVS(project, variant)) {
String config = getConfig(project, variant);
File xapFile = internal
.resolveFile("%package-output-dir%/project/bin/" + config
+ "/%app-name%.xap");
return createBuildResult(xapFile);
} else {
File csProjFile = internal
.resolveFile("%package-output-dir%/project");
Map<String, List<File>> buildResult = new HashMap<String, List<File>>();
buildResult.put(WinMobileCSPackager.PROJECT_FILE,
Arrays.asList(csProjFile));
return buildResult;
}
}
@Override
public void addPlatformSpecifics(MoSyncProject project,
IBuildVariant variant, CommandLineBuilder commandLine)
throws Exception {
DefaultPackager internal = new DefaultPackager(project, variant);
commandLine.flag("--cs-output").with(
internal.resolveFile("%program-output%").getParent());
if (!shouldBuildWithVS(project, variant)) {
commandLine.flag("--wp-project-only");
} else {
commandLine.flag("--wp-vs-build-path").with(MSBuild.getDefault().getToolPath());
}
String target = isEmulatorBuild(project, variant) ? "emulator"
: "device";
commandLine.flag("--wp-target").with(target);
String config = getConfig(project, variant);
commandLine.flag("--wp-config").with(config);
commandLine.flag("--wp-guid").with(
project.getProperty(PropertyInitializer.GUID));
if (getOutputType(project) == MoSyncBuilder.OUTPUT_TYPE_NATIVE_COMPILE) {
ArrayList<IPath> includePaths = new ArrayList<IPath>();
getNativePathsAndModules(project, variant, includePaths, null);
commandLine.flag("--wp-include-paths").with(Util.join(includePaths.toArray(), ";"));
Map<String, String> defines = MoSyncBuilder.extractMacroDefinesFromGCCArgs(project, variant);
for (Map.Entry<String, String> define : defines.entrySet()) {
String defineStr = Util.isEmpty(define.getValue()) ?
define.getKey() :
define.getKey() + "=" + define.getValue();
commandLine.param("--wp-macro-define");
commandLine.param(defineStr);
}
}
}
private String getConfig(MoSyncProject project, IBuildVariant variant) {
IBuildConfiguration cfg = project.getBuildConfiguration(variant
.getConfigurationId());
boolean isDebugBuild = cfg != null
&& cfg.getTypes().contains(IBuildConfiguration.DEBUG_TYPE);
if (MoSyncBuilder.OUTPUT_TYPE_STATIC_RECOMPILATION.equals(MoSyncBuilder.getPropertyOwner(project, variant.getConfigurationId()).getProperty(MoSyncBuilder.OUTPUT_TYPE))) {
return isDebugBuild ? "rebuild_debug" : "rebuild_release";
} else {
return isDebugBuild ? "Debug" : "Release";
}
}
private boolean shouldBuildWithVS(MoSyncProject project,
IBuildVariant variant) {
boolean generateOnly = !AbstractTool.isWindows()
|| !shouldBuildWithVSPref(project);
return MSBuild.getDefault().isValid() && (!generateOnly || isEmulatorBuild(project, variant));
}
private boolean shouldBuildWithVSPref(MoSyncProject project) {
return WinMobileCSPlugin.getDefault().getPreferenceStore()
.getBoolean(WinMobileCSPlugin.BUILD_WITH_VS);
}
private boolean isEmulatorBuild(MoSyncProject project, IBuildVariant variant) {
return variant.getSpecifiers().containsKey(
WinMobileCSPlugin.WP_EMULATOR_SPECIFIER);
}
@Override
public String getGenerateMode(IProfile profile) {
return BUILD_GEN_CS_MODE;
}
@Override
public void buildNative(MoSyncProject project, IBuildSession session,
IBuildVariant variant, IBuildResult result) throws Exception {
// All native building is performed in the package tool for WP.
}
// Temporary thing, remove after beta
private Boolean hasNativeSupport = null;
protected boolean supportsOutputType(String outputType) {
if (hasNativeSupport == null) {
hasNativeSupport = MoSyncTool.getDefault().getMoSyncLib().append(new Path("windowsphone8")).toFile().exists();
}
return hasNativeSupport || !MoSyncBuilder.OUTPUT_TYPE_NATIVE_COMPILE.equals(outputType);
}
}