Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordschaefer2017-07-04 21:40:52 -0400
committerDoug Schaefer2017-07-05 10:18:36 -0400
commitc4990122acf16dda1213bfc76f0f39359e3a102d (patch)
treeb59018298f5ef221c490d21a725ecccf6b129ac4 /windows/org.eclipse.cdt.msw.build
parentdd07cba37b21b6c2a690bb7123f2a3fe7d64c5ec (diff)
downloadorg.eclipse.cdt-c4990122acf16dda1213bfc76f0f39359e3a102d.tar.gz
org.eclipse.cdt-c4990122acf16dda1213bfc76f0f39359e3a102d.tar.xz
org.eclipse.cdt-c4990122acf16dda1213bfc76f0f39359e3a102d.zip
Bug 519190 - Get CMake working with MSVC toolchain
Adds in Core Build support for the MSVC toolchain. Fixes issue with PATH in the core build configuration since on Windows it's often Path. Change-Id: I3eb201bc22bf42341207e8f3bbef999d4d174f05 (cherry picked from commit 7f3745c765b0ea60a64218877ffd8cc748349f94)
Diffstat (limited to 'windows/org.eclipse.cdt.msw.build')
-rw-r--r--windows/org.eclipse.cdt.msw.build/plugin.xml7
-rw-r--r--windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChain.java281
-rw-r--r--windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChainProvider.java81
3 files changed, 369 insertions, 0 deletions
diff --git a/windows/org.eclipse.cdt.msw.build/plugin.xml b/windows/org.eclipse.cdt.msw.build/plugin.xml
index 922acd93c4..522cda8800 100644
--- a/windows/org.eclipse.cdt.msw.build/plugin.xml
+++ b/windows/org.eclipse.cdt.msw.build/plugin.xml
@@ -735,5 +735,12 @@
</toolChain>
</template>
</extension>
+ <extension
+ point="org.eclipse.cdt.core.toolChainProvider">
+ <provider
+ class="org.eclipse.cdt.msw.build.core.MSVCToolChainProvider"
+ id="org.eclipse.cdt.msw.build">
+ </provider>
+ </extension>
</plugin>
diff --git a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChain.java b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChain.java
new file mode 100644
index 0000000000..384d017e60
--- /dev/null
+++ b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChain.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright (c) 2017 QNX Software Systems 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
+ *******************************************************************************/
+package org.eclipse.cdt.msw.build.core;
+
+import java.io.File;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.build.IToolChain;
+import org.eclipse.cdt.core.build.IToolChainProvider;
+import org.eclipse.cdt.core.envvar.EnvironmentVariable;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
+import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
+import org.eclipse.core.resources.IBuildConfiguration;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PlatformObject;
+import org.osgi.framework.Version;
+
+public class MSVCToolChain extends PlatformObject implements IToolChain {
+
+ private final IToolChainProvider provider;
+ private final Path path;
+ private final Map<String, String> properties = new HashMap<>();
+ private final String id;
+ private final String arch;
+ private final String version;
+ private final IEnvironmentVariable pathVar;
+ private final IEnvironmentVariable includeVar;
+ private final IEnvironmentVariable libVar;
+ private final String[] includeDirs;
+ private final Map<String, String> symbols;
+
+ public MSVCToolChain(IToolChainProvider provider, Path path) {
+ this.provider = provider;
+ this.path = path;
+
+ // path = <version>/bin/<hostArch>/<targetArch>
+ String targetArch = path.getFileName().toString();
+ this.arch = targetArch.equalsIgnoreCase("x86") ? Platform.ARCH_X86 : Platform.ARCH_X86_64; //$NON-NLS-1$
+ this.id = "msvc." + arch; //$NON-NLS-1$
+ this.version = path.getParent().getParent().getParent().getFileName().toString();
+
+ Path kitRoot = Paths.get("C:", "Program Files (x86)", "Windows Kits", "10"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ List<String> versions = Arrays.asList(kitRoot.resolve("lib").toFile().list()); //$NON-NLS-1$
+ Collections.sort(versions, (v1, v2) -> {
+ Version ver1;
+ try {
+ ver1 = new Version(v1);
+ } catch (IllegalArgumentException e) {
+ return 1;
+ }
+
+ Version ver2;
+ try {
+ ver2 = new Version(v2);
+ } catch (IllegalArgumentException e) {
+ return -1;
+ }
+
+ return ver2.compareTo(ver1);
+ });
+ String sdkVersion = versions.iterator().next();
+
+ pathVar = new EnvironmentVariable("Path", String.join(File.pathSeparator, //$NON-NLS-1$
+ path.toString(),
+ kitRoot.resolve("bin").resolve(sdkVersion).resolve(targetArch).toString() //$NON-NLS-1$
+ ), IEnvironmentVariable.ENVVAR_PREPEND, File.pathSeparator);
+
+ this.includeDirs = new String[] {
+ path.getParent().getParent().getParent().resolve("include").toString(), //$NON-NLS-1$
+ kitRoot.resolve("include").resolve(sdkVersion).resolve("ucrt").toString(), //$NON-NLS-1$ //$NON-NLS-2$
+ kitRoot.resolve("include").resolve(sdkVersion).resolve("shared").toString(), //$NON-NLS-1$ //$NON-NLS-2$
+ kitRoot.resolve("include").resolve(sdkVersion).resolve("um").toString(), //$NON-NLS-1$ //$NON-NLS-2$
+ kitRoot.resolve("include").resolve(sdkVersion).resolve("winrt").toString() //$NON-NLS-1$ //$NON-NLS-2$
+ };
+
+ includeVar = new EnvironmentVariable("INCLUDE", String.join(File.pathSeparator, this.includeDirs), //$NON-NLS-1$
+ IEnvironmentVariable.ENVVAR_REPLACE, File.pathSeparator);
+
+ libVar = new EnvironmentVariable("LIB", String.join(File.pathSeparator, //$NON-NLS-1$
+ path.getParent().getParent().getParent().resolve("lib").resolve(targetArch).toString(), //$NON-NLS-1$
+ kitRoot.resolve("lib").resolve(sdkVersion).resolve("ucrt").resolve(targetArch).toString(), //$NON-NLS-1$ //$NON-NLS-2$
+ kitRoot.resolve("lib").resolve(sdkVersion).resolve("um").resolve(targetArch).toString() //$NON-NLS-1$ //$NON-NLS-2$
+ ), IEnvironmentVariable.ENVVAR_REPLACE, File.pathSeparator);
+
+ symbols = new HashMap<>();
+ symbols.put("_WIN32", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (this.arch.equals(Platform.ARCH_X86)) {
+ symbols.put("_M_IX86", "600"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ symbols.put("_WIN64", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("_M_X64", "100"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ // TODO make this more dynamic to actual version
+ symbols.put("_MSC_VER", "1900"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Microsoft specific modifiers that can be ignored
+ symbols.put("__cdecl", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__fastcall", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__restrict", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__sptr", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__stdcall", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__unaligned", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__uptr", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__w64", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Redefine some things so that the CDT parser can handle them, until there is a VC specific parser
+ symbols.put("__forceinline", "__inline"); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__int8", "char"); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__int16", "short"); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__int32", "int"); //$NON-NLS-1$ //$NON-NLS-2$
+ symbols.put("__int64", "long long"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public IToolChainProvider getProvider() {
+ return provider;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String getVersion() {
+ return version;
+ }
+
+ @Override
+ public String getName() {
+ return "Visual C++";
+ }
+
+ @Override
+ public String getProperty(String key) {
+ String value = properties.get(key);
+ if (value != null) {
+ return value;
+ }
+
+ // By default, we're a local GCC
+ switch (key) {
+ case ATTR_OS:
+ return Platform.OS_WIN32;
+ case ATTR_ARCH:
+ return arch;
+ }
+
+ return null;
+ }
+
+ @Override
+ public void setProperty(String key, String value) {
+ properties.put(key, value);
+ }
+
+ @Override
+ public IEnvironmentVariable[] getVariables() {
+ return new IEnvironmentVariable[] { pathVar, includeVar, libVar };
+ }
+
+ @Override
+ public IEnvironmentVariable getVariable(String name) {
+ switch (name) {
+ case "PATH": //$NON-NLS-1$
+ case "Path": //$NON-NLS-1$
+ return pathVar;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public String[] getErrorParserIds() {
+ return new String[] { CCorePlugin.PLUGIN_ID + ".VCErrorParser" //$NON-NLS-1$
+ };
+ }
+
+ @Override
+ public String getBinaryParserId() {
+ return CCorePlugin.PLUGIN_ID + ".PE"; //$NON-NLS-1$
+ }
+
+ @Override
+ public Path getCommandPath(Path command) {
+ if (command.isAbsolute()) {
+ return command;
+ } else {
+ return this.path.resolve(command);
+ }
+ }
+
+ @Override
+ public String[] getCompileCommands() {
+ return new String[] { "cl", "cl.exe" //$NON-NLS-1$ //$NON-NLS-2$
+ };
+ }
+
+ @Override
+ public IExtendedScannerInfo getDefaultScannerInfo(IBuildConfiguration buildConfig,
+ IExtendedScannerInfo baseScannerInfo, ILanguage language, URI buildDirectoryURI) {
+ return new ExtendedScannerInfo(symbols, includeDirs);
+ }
+
+ @Override
+ public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, List<String> command,
+ IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) {
+ Map<String, String> symbols = new HashMap<>(this.symbols);
+ List<String> includeDirs = new ArrayList<>(Arrays.asList(this.includeDirs));
+
+ for (String arg : command) {
+ if (arg.startsWith("-") || arg.startsWith("/")) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (arg.charAt(1) == 'I') {
+ includeDirs.add(arg.substring(2));
+ } else if (arg.charAt(1) == 'D') {
+ String[] define = arg.substring(2).split("="); //$NON-NLS-1$
+ if (define.length == 1) {
+ symbols.put(define[0], "1"); //$NON-NLS-1$
+ } else {
+ symbols.put(define[0], define[1]);
+ }
+ }
+ }
+ }
+
+ return new ExtendedScannerInfo(symbols, includeDirs.toArray(new String[includeDirs.size()]));
+ }
+
+ @Override
+ public IResource[] getResourcesFromCommand(List<String> command, URI buildDirectoryURI) {
+ // Start at the back looking for arguments
+ // TODO this was copied from the GCCToolChain, good candidate for the default implementation
+ List<IResource> resources = new ArrayList<>();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ for (int i = command.size() - 1; i >= 0; --i) {
+ String arg = command.get(i);
+ if (arg.startsWith("-") || arg.startsWith("/")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // ran into an option, we're done.
+ break;
+ }
+ Path srcPath = Paths.get(arg);
+ URI uri;
+ if (srcPath.isAbsolute()) {
+ uri = srcPath.toUri();
+ } else {
+ try {
+ uri = buildDirectoryURI.resolve(arg);
+ } catch (IllegalArgumentException e) {
+ // Bad URI
+ continue;
+ }
+ }
+
+ for (IFile resource : root.findFilesForLocationURI(uri)) {
+ resources.add(resource);
+ }
+ }
+
+ return resources.toArray(new IResource[resources.size()]);
+ }
+}
diff --git a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChainProvider.java b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChainProvider.java
new file mode 100644
index 0000000000..15e928a65a
--- /dev/null
+++ b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/core/MSVCToolChainProvider.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2017 QNX Software Systems 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
+ *******************************************************************************/
+package org.eclipse.cdt.msw.build.core;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.eclipse.cdt.core.build.IToolChain;
+import org.eclipse.cdt.core.build.IToolChainManager;
+import org.eclipse.cdt.core.build.IToolChainProvider;
+import org.eclipse.cdt.msw.build.Activator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Toolchain provider for Microsoft's Visual C++ Compiler (MSVC).
+ *
+ * This implementation only supports Microsoft Build Tools 2017 and
+ * the Windows 10 SDK (Kit).
+ */
+public class MSVCToolChainProvider implements IToolChainProvider {
+
+ public MSVCToolChainProvider() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public String getId() {
+ return "org.eclipse.cdt.msw.build"; //$NON-NLS-1$
+ }
+
+ @Override
+ public void init(IToolChainManager manager) throws CoreException {
+ // See if cl is installed
+ Path vsPath = Paths.get("C:", "Program Files (x86)", "Microsoft Visual Studio"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (!Files.exists(vsPath)) {
+ return;
+ }
+
+ Path vs2017Path = vsPath.resolve("2017"); //$NON-NLS-1$
+ if (!Files.exists(vs2017Path)) {
+ return;
+ }
+
+ Path msvcPath = vs2017Path.resolve("BuildTools").resolve("VC").resolve("Tools").resolve("MSVC"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ if (!Files.exists(msvcPath)) {
+ return;
+ }
+
+ String hostPath = Platform.getOSArch().equals(Platform.ARCH_X86) ? "HostX86" : "HostX64"; //$NON-NLS-1$ //$NON-NLS-2$
+ String archPath = Platform.getOSArch().equals(Platform.ARCH_X86) ? "x86" : "x64"; //$NON-NLS-1$ //$NON-NLS-2$
+
+ try {
+ Files.find(msvcPath, 6, (path, attr) -> {
+ return path.getFileName().toString().equalsIgnoreCase("cl.exe") //$NON-NLS-1$
+ && path.getParent().getParent().getFileName().toString().equalsIgnoreCase(hostPath)
+ && path.getParent().getFileName().toString().equalsIgnoreCase(archPath);
+ }).forEach((path) -> {
+ manager.addToolChain(new MSVCToolChain(this, path.getParent()));
+ });
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Finding cl.exe", e)); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public IToolChain getToolChain(String id, String version) throws CoreException {
+ // TODO Auto-generated method stub
+ return IToolChainProvider.super.getToolChain(id, version);
+ }
+
+}

Back to the top