/******************************************************************************* * Copyright (c) 2015 ARM Ltd. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * ARM Ltd and ARM Germany GmbH - Initial API and implementation * Liviu Ionescu - review, testing and enhancements *******************************************************************************/ package com.arm.cmsis.pack.build.gnuarmeclipse; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.eclipse.cdt.managedbuilder.core.IOption; import com.arm.cmsis.pack.build.IBuildSettings; import com.arm.cmsis.pack.build.settings.RteToolChainAdapter; import com.arm.cmsis.pack.common.CmsisConstants; /** * Toolchain adapter for GNU ARM C/C++ Cross Compiler<br> * See: <a * href="http://gnuarmeclipse.livius.net">"http://gnuarmeclipse.livius.net"</a><br> */ public class GnuarmeclipseToolChainAdapter extends RteToolChainAdapter { static public final String GNUARMECLIPSE_TOOLCHAIN_PREFIX = "ilg.gnuarmeclipse.managedbuild.cross"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_TOOLCHAIN_ID = GNUARMECLIPSE_TOOLCHAIN_PREFIX + ".toolchain.base"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_OPTION = GNUARMECLIPSE_TOOLCHAIN_PREFIX + ".option"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_ARM_TARGET = GNUARMECLIPSE_OPTION + ".arm.target"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_CPU_OPTION = GNUARMECLIPSE_ARM_TARGET + ".family"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_FPU_OPTION = GNUARMECLIPSE_ARM_TARGET + ".fpu.unit"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_FPU_ABI_OPTION = GNUARMECLIPSE_ARM_TARGET + ".fpu.abi"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_ENDIAN_OPTION = GNUARMECLIPSE_ARM_TARGET + ".endianness"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_INSTR_SET_OPTION = GNUARMECLIPSE_ARM_TARGET + ".instructionset"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_LINKER_SCRIPT_OPTION = GNUARMECLIPSE_OPTION + ".base.linker.scriptfile"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_CPU_VALUE_PREFIX = GNUARMECLIPSE_ARM_TARGET + ".mcpu."; //$NON-NLS-1$ static public final String GNUARMECLIPSE_FPU_VALUE_PREFIX = GNUARMECLIPSE_ARM_TARGET + ".fpu.unit."; //$NON-NLS-1$ static public final String GNUARMECLIPSE_FPU_ABI_VALUE_PREFIX = GNUARMECLIPSE_ARM_TARGET + ".fpu.abi."; //$NON-NLS-1$ static public final String GNUARMECLIPSE_ENDIAN_VALUE_PREFIX = GNUARMECLIPSE_ARM_TARGET + ".endianness."; //$NON-NLS-1$ static public final String GNUARMECLIPSE_INSTR_SET_VALUE_PREFIX = GNUARMECLIPSE_ARM_TARGET + ".instructionset."; //$NON-NLS-1$ static public final String GNUARMECLIPSE_CMISC_OPTION = GNUARMECLIPSE_OPTION + ".base.compiler.other"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_AMISC_OPTION = GNUARMECLIPSE_OPTION + ".assembler.other"; //$NON-NLS-1$ static public final String GNUARMECLIPSE_LMISC_OPTION = GNUARMECLIPSE_OPTION + ".base.linker.other"; //$NON-NLS-1$ @Override protected int getRteOptionType(String id) { switch (id) { case GNUARMECLIPSE_CPU_OPTION: return IBuildSettings.CPU_OPTION; case GNUARMECLIPSE_FPU_OPTION: return IBuildSettings.FPU_OPTION; case GNUARMECLIPSE_FPU_ABI_OPTION: return IBuildSettings.FLOAT_ABI_OPTION; case GNUARMECLIPSE_ENDIAN_OPTION: return IBuildSettings.ENDIAN_OPTION; case GNUARMECLIPSE_INSTR_SET_OPTION: return IBuildSettings.INSTR_SET_OPTION; case GNUARMECLIPSE_LINKER_SCRIPT_OPTION: return IBuildSettings.RTE_LINKER_SCRIPT; // misc options are here for completeness case GNUARMECLIPSE_CMISC_OPTION: return IBuildSettings.CMISC_OPTION; case GNUARMECLIPSE_AMISC_OPTION: return IBuildSettings.AMISC_OPTION; case GNUARMECLIPSE_LMISC_OPTION: return IBuildSettings.LMISC_OPTION; default: break; } return IBuildSettings.UNKNOWN_OPTION; } @Override protected String getRteOptionValue(int oType, IBuildSettings buildSettings, IOption option) { switch (oType) { case IBuildSettings.CPU_OPTION: return getCpuOptionValue(buildSettings); case IBuildSettings.INSTR_SET_OPTION: return GNUARMECLIPSE_INSTR_SET_VALUE_PREFIX + "thumb"; //$NON-NLS-1$ case IBuildSettings.ENDIAN_OPTION: return getEndianOptionValue(buildSettings); case IBuildSettings.FPU_OPTION: return getFpuOptionValue(buildSettings); case IBuildSettings.FLOAT_ABI_OPTION: return getFloatAbiOptionValue(buildSettings); case IBuildSettings.RTE_LINKER_SCRIPT: return null; // reported via getStringListValue() default: break; } return super.getRteOptionValue(oType, buildSettings, option); } @Override protected Collection<String> getStringListValue(IBuildSettings buildSettings, int type) { if (type == IBuildSettings.RTE_LIBRARIES || type == IBuildSettings.RTE_LIBRARY_PATHS) { return null; // we add libraries as objects => ignore libs and lib // paths } else if (type == IBuildSettings.RTE_OBJECTS) { Collection<String> objs = buildSettings.getStringListValue(IBuildSettings.RTE_OBJECTS); List<String> value = new LinkedList<String>(); if (objs != null && !objs.isEmpty()) value.addAll(objs); // add libraries as objects (gcc does not allow to specify libs with // absolute paths) Collection<String> libs = buildSettings.getStringListValue(IBuildSettings.RTE_LIBRARIES); if (libs != null && !libs.isEmpty()) value.addAll(libs); return value; } return super.getStringListValue(buildSettings, type); } /** * Returns value for CPU_OPTION * * @param buildSettings * settings to get required information from * @return CPU_OPTION value string */ protected String getCpuOptionValue(IBuildSettings buildSettings) { String cpu = getDeviceAttribute(IBuildSettings.CPU_OPTION, buildSettings); int pos = cpu.indexOf('+'); if (pos > 0) { // Cortex-M0+ -> Cortex-M0plus cpu = cpu.substring(0, pos); cpu += "plus"; //$NON-NLS-1$ } return GNUARMECLIPSE_CPU_VALUE_PREFIX + cpu.toLowerCase(); } /** * Returns enum value for FPU_OPTION * * @param buildSettings * settings to get required information from * @return FPU_OPTION value string */ public String getFpuOptionValue(IBuildSettings buildSettings) { String cpu = getDeviceAttribute(IBuildSettings.CPU_OPTION, buildSettings); String fpu = getDeviceAttribute(IBuildSettings.FPU_OPTION, buildSettings); String val = "default"; //$NON-NLS-1$ if (cpu == null || fpu == null || fpu.equals(CmsisConstants.NO_FPU) || !coreHasFpu(cpu)) { // default } else { if (cpu.equals("Cortex-M7")) { //$NON-NLS-1$ if (fpu.equals(CmsisConstants.SP_FPU)) val = "fpv5spd16"; //$NON-NLS-1$ if (fpu.equals(CmsisConstants.DP_FPU)) val = "fpv5d16"; //$NON-NLS-1$ } else if (fpu.equals(CmsisConstants.SP_FPU)) { val = "fpv4spd16"; //$NON-NLS-1$ } } return GNUARMECLIPSE_FPU_VALUE_PREFIX + val; } /** * Returns enum value for FLOAT_ABI_OPTION * * @param buildSettings * settings to get required information from * @return FPU_OPTION value string */ public String getFloatAbiOptionValue(IBuildSettings buildSettings) { String cpu = getDeviceAttribute(IBuildSettings.CPU_OPTION, buildSettings); String fpu = getDeviceAttribute(IBuildSettings.FPU_OPTION, buildSettings); String val; if (cpu == null || fpu == null || fpu.equals(CmsisConstants.NO_FPU) || !coreHasFpu(cpu)) val = "default"; //$NON-NLS-1$ else val = "hard"; //$NON-NLS-1$ return GNUARMECLIPSE_FPU_ABI_VALUE_PREFIX + val; } protected String getEndianOptionValue(IBuildSettings buildSettings) { String endian = getDeviceAttribute(IBuildSettings.ENDIAN_OPTION, buildSettings); String val; if (endian == null || endian.isEmpty()) { val = "default"; //$NON-NLS-1$ } else if (endian.equals(CmsisConstants.LITTLENDIAN)) { val = "little"; //$NON-NLS-1$ } else if (endian.equals(CmsisConstants.BIGENDIAN)) { val = "big"; //$NON-NLS-1$ } else { val = "default"; //$NON-NLS-1$ } return GNUARMECLIPSE_ENDIAN_VALUE_PREFIX + val; } }