1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Bug 530000 - Add Meson Build support

- initial contribution of Meson Build support based upon
  Core Build CMake

Change-Id: I9a91901254b7750f4f5eef69ed5375a5c1cce0a4
This commit is contained in:
Jeff Johnston 2018-01-30 15:46:07 -05:00
parent 55fb64151b
commit 127e71423e
62 changed files with 3617 additions and 0 deletions

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.meson-feature</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.pde.FeatureBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.FeatureNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,2 @@
bin.includes = feature.xml,\
feature.properties

View file

@ -0,0 +1,17 @@
###############################################################################
# Copyright (c) 2018 Red Hat Inc. 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
###############################################################################
featureName=C/C++ Meson Build Support - Preview
providerName=Eclipse CDT
description=Support for projects built using Meson
copyright=\
Copyright (c) 2018 Red Hat Inc. and others.\n\
All rights reserved. This program and the accompanying materials\n\
are made available under the terms of the Eclipse Public License v1.0\n\
which accompanies this distribution, and is available at\n\
http://www.eclipse.org/legal/epl-v10.html

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="org.eclipse.cdt.meson"
label="%featureName"
version="9.4.0.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
<description>
%description
</description>
<copyright>
%copyright
</copyright>
<license url="%licenseURL">
%license
</license>
<plugin
id="org.eclipse.cdt.meson.core"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="org.eclipse.cdt.meson.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.meson.core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ds.core.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundler-Name.0
Bundle-SymbolicName: org.eclipse.cdt.meson.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.cdt.meson.core.Activator
Bundle-Vendor: %provider
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.cdt.core;bundle-version="6.4.0",
org.eclipse.tools.templates.freemarker
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Import-Package: com.google.gson
Export-Package: org.eclipse.cdt.internal.meson.core;x-friends:="org.eclipse.cdt.meson.ui",
org.eclipse.cdt.meson.core
Service-Component: OSGI-INF/component.xml

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.cdt.meson.core">
<implementation class="org.eclipse.cdt.internal.meson.core.MesonToolChainManager"/>
<service>
<provide interface="org.eclipse.cdt.meson.core.IMesonToolChainManager"/>
</service>
</scr:component>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 22, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
</body></html>

View file

@ -0,0 +1,10 @@
output.. = bin/
bin.includes = META-INF/,\
.,\
schema/,\
templates/,\
plugin.properties,\
plugin.xml,\
about.html,\
OSGI-INF/,
source.. = src/

View file

@ -0,0 +1,3 @@
edHatVendor.name = Red Hat
Bundle-Name.0 = Meson Plug-in
provider=Eclipse CDT

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="toolChainProvider" name="Meson ToolChain File Provider" schema="schema/toolChainProvider.exsd"/>
<extension
id="mesonNature"
point="org.eclipse.core.resources.natures">
<runtime>
<run
class="org.eclipse.cdt.meson.core.MesonNature">
</run>
</runtime>
</extension>
<extension
point="org.eclipse.cdt.core.buildConfigProvider">
<provider
class="org.eclipse.cdt.internal.meson.core.MesonBuildConfigurationProvider"
id="org.eclipse.cdt.meson.core.provider"
natureId="org.eclipse.cdt.meson.core.mesonNature">
</provider>
</extension>
</plugin>

View file

@ -0,0 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.meson.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.cdt.meson.core" id="toolChainProvider" name="Meson ToolChain File Provider"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence minOccurs="1" maxOccurs="unbounded">
<element ref="provider"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="provider">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.meson.core.IMesonToolChainProvider"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
</schema>

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2016 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.internal.meson.core;
public class CompileCommand {
private String directory;
private String command;
private String file;
public String getDirectory() {
return directory;
}
public String getCommand() {
return command;
}
public String getFile() {
return file;
}
}

View file

@ -0,0 +1,299 @@
/*******************************************************************************
* Copyright (c) 2015, 2016 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.internal.meson.core;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CommandLauncherManager;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.CBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildCommandLauncher;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.cdt.meson.core.IMesonConstants;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.cdt.meson.core.IMesonToolChainManager;
import org.eclipse.cdt.utils.Platform;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import com.google.gson.Gson;
public class MesonBuildConfiguration extends CBuildConfiguration {
private static final String TOOLCHAIN_FILE = "cdt.meson.toolchainfile"; //$NON-NLS-1$
private IMesonToolChainFile toolChainFile;
public MesonBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
super(config, name);
IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class);
Preferences settings = getSettings();
String pathStr = settings.get(TOOLCHAIN_FILE, ""); //$NON-NLS-1$
if (!pathStr.isEmpty()) {
Path path = Paths.get(pathStr);
toolChainFile = manager.getToolChainFile(path);
} else {
toolChainFile = manager.getToolChainFileFor(getToolChain());
if (toolChainFile != null) {
saveToolChainFile();
}
}
}
public MesonBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) {
this(config, name, toolChain, null, "run"); //$NON-NLS-1$
}
public MesonBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain,
IMesonToolChainFile toolChainFile, String launchMode) {
super(config, name, toolChain, launchMode);
this.toolChainFile = toolChainFile;
if (toolChainFile != null) {
saveToolChainFile();
}
}
private void saveToolChainFile() {
Preferences settings = getSettings();
settings.put(TOOLCHAIN_FILE, toolChainFile.getPath().toString());
try {
settings.flush();
} catch (BackingStoreException e) {
Activator.log(e);
}
}
private boolean isLocal() throws CoreException {
IToolChain toolchain = getToolChain();
return Platform.getOS().equals(toolchain.getProperty(IToolChain.ATTR_OS))
&& Platform.getOSArch().equals(toolchain.getProperty(IToolChain.ATTR_ARCH));
}
@Override
public IProject[] build(int kind, Map<String, String> args, IConsole console, IProgressMonitor monitor)
throws CoreException {
IProject project = getProject();
try {
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
ConsoleOutputStream outStream = console.getOutputStream();
Path buildDir = getBuildDirectory();
outStream.write(String.format(Messages.MesonBuildConfiguration_BuildingIn, buildDir.toString()));
// Make sure we have a toolchain file if cross
if (toolChainFile == null && !isLocal()) {
IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class);
toolChainFile = manager.getToolChainFileFor(getToolChain());
if (toolChainFile == null) {
// error
console.getErrorStream().write(Messages.MesonBuildConfiguration_NoToolchainFile);
return null;
}
}
boolean runMeson = !Files.exists(buildDir.resolve("build.ninja")); //$NON-NLS-1$
if (runMeson) { // $NON-NLS-1$
Path path = findCommand("meson"); //$NON-NLS-1$
if (path == null) {
path = Paths.get("meson"); //$NON-NLS-1
}
List<String> argsList = new ArrayList<>();
String userArgs = getProperty(IMesonConstants.MESON_ARGUMENTS);
if (userArgs != null) {
argsList.addAll(Arrays.asList(userArgs.trim().split("\\s+"))); //$NON-NLS-1$
}
argsList.add(getBuildDirectory().toString());
String envStr = getProperty(IMesonConstants.MESON_ENV);
String[] env = new String[0];
if (envStr != null) {
env = envStr.split(IMesonConstants.MESON_ENV_SEPARATOR); //$NON-NLS-1$
}
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(this);
launcher.setProject(getProject());
if (launcher instanceof ICBuildCommandLauncher) {
((ICBuildCommandLauncher)launcher).setBuildConfiguration(this);
}
monitor.subTask(Messages.MesonBuildConfiguration_RunningMeson);
org.eclipse.core.runtime.Path mesonPath = new org.eclipse.core.runtime.Path(path.toString());
outStream.write(String.join(" ", envStr != null ? envStr : "", //$NON-NLS-1$ //$NON-NLS-2$
mesonPath.toString(), userArgs, "\n")); //$NON-NLS-1$
outStream.write(getBuildDirectory() + "\n"); //$NON-NLS-1$
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(getBuildDirectory().getParent().getParent().toString());
launcher.execute(mesonPath, argsList.toArray(new String[0]), env, workingDir, monitor);
if (launcher.waitAndRead(outStream, outStream, SubMonitor.convert(monitor)) != ICommandLauncher.OK) {
String errMsg = launcher.getErrorMessage();
console.getErrorStream().write(String.format(Messages.MesonBuildConfiguration_RunningMesonFailure, errMsg));
return null;
};
}
try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this,
getToolChain().getErrorParserIds())) {
epm.setOutputStream(console.getOutputStream());
String buildCommand = getProperty(IMesonConstants.BUILD_COMMAND);
if (buildCommand == null || buildCommand.isEmpty()) {
buildCommand = "ninja";
}
String envStr = getProperty(IMesonConstants.MESON_ENV);
String[] env = new String[0];
if (envStr != null) {
env = envStr.split(envStr);
}
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(this);
launcher.setProject(getProject());
if (launcher instanceof ICBuildCommandLauncher) {
((ICBuildCommandLauncher)launcher).setBuildConfiguration(this);
}
monitor.subTask(Messages.MesonBuildConfiguration_RunningMeson);
org.eclipse.core.runtime.Path ninjaPath = new org.eclipse.core.runtime.Path(buildCommand);
outStream.write(String.join(" ", ninjaPath.toString() + '\n')); //$NON-NLS-1$
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(getBuildDirectory().toString());
launcher.execute(ninjaPath, new String[0], env, workingDir, monitor);
if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), SubMonitor.convert(monitor)) != ICommandLauncher.OK) {
String errMsg = launcher.getErrorMessage();
console.getErrorStream().write(String.format(Messages.MesonBuildConfiguration_RunningNinjaFailure, errMsg));
return null;
};
}
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
// Load compile_commands.json file
processCompileCommandsFile(monitor);
outStream.write(String.format(Messages.MesonBuildConfiguration_BuildingComplete, buildDir.toString()));
return new IProject[] { project };
} catch (IOException e) {
throw new CoreException(Activator.errorStatus(String.format(Messages.MesonBuildConfiguration_Building, project.getName()), e));
}
}
@Override
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
try {
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
ConsoleOutputStream outStream = console.getOutputStream();
Path buildDir = getBuildDirectory();
try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this,
getToolChain().getErrorParserIds())) {
epm.setOutputStream(console.getOutputStream());
String cleanCommand = getProperty(IMesonConstants.CLEAN_COMMAND);
if (cleanCommand == null) {
cleanCommand = "ninja clean"; //$NON-NLS-1$
}
String[] command = cleanCommand.split(" "); //$NON-NLS-1$
Path cmdPath = findCommand(command[0]);
if (cmdPath != null) {
command[0] = cmdPath.toString();
}
IPath cmd = new org.eclipse.core.runtime.Path(command[0]);
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(this);
launcher.setProject(getProject());
if (launcher instanceof ICBuildCommandLauncher) {
((ICBuildCommandLauncher)launcher).setBuildConfiguration(this);
}
String[] commandargs = new String[0];
if (command.length > 1) {
commandargs = Arrays.copyOfRange(command, 1, command.length);
}
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(buildDir.toString());
String[] env = new String[0];
outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$
launcher.execute(cmd, commandargs, env, workingDir, monitor);
if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(), SubMonitor.convert(monitor)) != ICommandLauncher.OK) {
String errMsg = launcher.getErrorMessage();
console.getErrorStream().write(String.format(Messages.MesonBuildConfiguration_RunningNinjaFailure, errMsg));
return;
};
}
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (IOException e) {
throw new CoreException(Activator.errorStatus(String.format(Messages.MesonBuildConfiguration_Cleaning, project.getName()), e));
}
}
private void processCompileCommandsFile(IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
Path commandsFile = getBuildDirectory().resolve("compile_commands.json"); //$NON-NLS-1$
if (Files.exists(commandsFile)) {
monitor.setTaskName(Messages.MesonBuildConfiguration_ProcCompJson);
try (FileReader reader = new FileReader(commandsFile.toFile())) {
Gson gson = new Gson();
CompileCommand[] commands = gson.fromJson(reader, CompileCommand[].class);
Map<String, CompileCommand> dedupedCmds = new HashMap<>();
for (CompileCommand command : commands) {
dedupedCmds.put(command.getFile(), command);
}
for (CompileCommand command : dedupedCmds.values()) {
processLine(command.getCommand());
}
shutdown();
} catch (IOException e) {
throw new CoreException(
Activator.errorStatus(String.format(Messages.MesonBuildConfiguration_ProcCompCmds, project.getName()), e));
}
}
}
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors
* Red Hat Inc. - modified for use with Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.core;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationProvider;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.cdt.meson.core.IMesonToolChainManager;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
public class MesonBuildConfigurationProvider implements ICBuildConfigurationProvider {
public static final String ID = "org.eclipse.cdt.meson.core.provider"; //$NON-NLS-1$
private IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class);
private ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class);
@Override
public String getId() {
return ID;
}
@Override
public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) {
IToolChain toolChain = null;
// try the toolchain for the local target
Map<String, String> properties = new HashMap<>();
properties.put(IToolChain.ATTR_OS, Platform.getOS());
properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch());
IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class);
for (IToolChain tc : toolChainManager.getToolChainsMatching(properties)) {
toolChain = tc;
break;
}
// local didn't work, try and find one that does
if (toolChain == null) {
for (IToolChain tc : toolChainManager.getToolChainsMatching(new HashMap<>())) {
toolChain = tc;
break;
}
}
if (toolChain != null) {
return new MesonBuildConfiguration(config, name, toolChain);
} else {
// No valid combinations
return null;
}
} else {
return new MesonBuildConfiguration(config, name);
}
}
@Override
public ICBuildConfiguration createBuildConfiguration(IProject project, IToolChain toolChain, String launchMode,
IProgressMonitor monitor) throws CoreException {
// get matching toolchain file if any
Map<String, String> properties = new HashMap<>();
String os = toolChain.getProperty(IToolChain.ATTR_OS);
if (os != null && !os.isEmpty()) {
properties.put(IToolChain.ATTR_OS, os);
}
String arch = toolChain.getProperty(IToolChain.ATTR_ARCH);
if (arch != null && !arch.isEmpty()) {
properties.put(IToolChain.ATTR_ARCH, arch);
}
IMesonToolChainFile file = manager.getToolChainFileFor(toolChain);
if (file == null) {
Collection<IMesonToolChainFile> files = manager.getToolChainFilesMatching(properties);
if (!files.isEmpty()) {
file = files.iterator().next();
}
}
// create config
StringBuilder configName = new StringBuilder("meson."); //$NON-NLS-1$
configName.append(launchMode);
if (os != null) {
configName.append('.');
configName.append(os);
}
if (arch != null && !arch.isEmpty()) {
configName.append('.');
configName.append(arch);
}
String name = configName.toString();
int i = 0;
while (configManager.hasConfiguration(this, project, name)) {
name = configName.toString() + '.' + (++i);
}
IBuildConfiguration config = configManager.createBuildConfiguration(this, project, name, monitor);
MesonBuildConfiguration mesonConfig = new MesonBuildConfiguration(config, name, toolChain, file,
launchMode);
configManager.addBuildConfiguration(config, mesonConfig);
return mesonConfig;
}
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.core;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.core.runtime.CoreException;
public class MesonToolChainFile implements IMesonToolChainFile {
String n;
private final Path path;
private IToolChain toolchain;
final Map<String, String> properties = new HashMap<>();
public MesonToolChainFile(String n, Path path) {
this.n = n;
this.path = path;
}
@Override
public Path getPath() {
return path;
}
@Override
public String getProperty(String key) {
return properties.get(key);
}
@Override
public void setProperty(String key, String value) {
properties.put(key, value);
}
@Override
public IToolChain getToolChain() throws CoreException {
if (toolchain == null) {
IToolChainManager tcManager = Activator.getService(IToolChainManager.class);
toolchain = tcManager.getToolChain(properties.get(MesonBuildConfiguration.TOOLCHAIN_TYPE),
properties.get(MesonBuildConfiguration.TOOLCHAIN_ID));
if (toolchain == null) {
Collection<IToolChain> tcs = tcManager.getToolChainsMatching(properties);
if (!tcs.isEmpty()) {
toolchain = tcs.iterator().next();
}
}
}
return toolchain;
}
boolean matches(Map<String, String> properties) {
for (Map.Entry<String, String> property : properties.entrySet()) {
if (!property.getValue().equals(getProperty(property.getKey()))) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,228 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use with Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.core;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.cdt.meson.core.IMesonToolChainListener;
import org.eclipse.cdt.meson.core.IMesonToolChainManager;
import org.eclipse.cdt.meson.core.IMesonToolChainProvider;
import org.eclipse.cdt.meson.core.MesonToolChainEvent;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class MesonToolChainManager implements IMesonToolChainManager {
private Map<Path, IMesonToolChainFile> files;
private static final String N = "n"; //$NON-NLS-1$
private static final String PATH = "__path"; //$NON-NLS-1$
private final List<IMesonToolChainListener> listeners = new LinkedList<>();
private Preferences getPreferences() {
return InstanceScope.INSTANCE.getNode(Activator.getPluginId()).node("mesonToolchains"); //$NON-NLS-1$
}
private void init() {
if (files == null) {
files = new HashMap<>();
Preferences prefs = getPreferences();
try {
for (String childName : prefs.childrenNames()) {
Preferences tcNode = prefs.node(childName);
String pathStr = tcNode.get(PATH, "/"); //$NON-NLS-1$
Path path = Paths.get(pathStr);
if (Files.exists(path) && !files.containsKey(path)) {
IMesonToolChainFile file = new MesonToolChainFile(childName, path);
for (String key : tcNode.keys()) {
String value = tcNode.get(key, ""); //$NON-NLS-1$
if (!value.isEmpty()) {
file.setProperty(key, value);
}
}
files.put(path, file);
} else {
tcNode.removeNode();
prefs.flush();
}
}
} catch (BackingStoreException e) {
Activator.log(e);
}
// TODO discovery
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getPluginId(),
"toolChainProvider"); //$NON-NLS-1$
for (IConfigurationElement element : point.getConfigurationElements()) {
if (element.getName().equals("provider")) { //$NON-NLS-1$
try {
IMesonToolChainProvider provider = (IMesonToolChainProvider) element
.createExecutableExtension("class"); //$NON-NLS-1$
provider.init(this);
} catch (ClassCastException | CoreException e) {
Activator.log(e);
}
}
}
}
}
@Override
public IMesonToolChainFile newToolChainFile(Path path) {
return new MesonToolChainFile(null, path);
}
@Override
public void addToolChainFile(IMesonToolChainFile file) {
init();
if (files.containsKey(file.getPath())) {
removeToolChainFile(file);
}
files.put(file.getPath(), file);
// save it
MesonToolChainFile realFile = (MesonToolChainFile) file;
Preferences prefs = getPreferences();
String n = realFile.n;
if (n == null) {
n = prefs.get(N, "0"); //$NON-NLS-1$
realFile.n = n;
}
prefs.put(N, Integer.toString(Integer.parseInt(n) + 1));
Preferences tcNode = prefs.node(n);
tcNode.put(PATH, file.getPath().toString());
for (Entry<String, String> entry : realFile.properties.entrySet()) {
tcNode.put(entry.getKey(), entry.getValue());
}
try {
prefs.flush();
} catch (BackingStoreException e) {
Activator.log(e);
}
fireEvent(new MesonToolChainEvent(MesonToolChainEvent.ADDED, file));
}
@Override
public void removeToolChainFile(IMesonToolChainFile file) {
init();
fireEvent(new MesonToolChainEvent(MesonToolChainEvent.REMOVED, file));
files.remove(file.getPath());
String n = ((MesonToolChainFile) file).n;
if (n != null) {
Preferences prefs = getPreferences();
Preferences tcNode = prefs.node(n);
try {
tcNode.removeNode();
prefs.flush();
} catch (BackingStoreException e) {
Activator.log(e);
}
}
}
@Override
public IMesonToolChainFile getToolChainFile(Path path) {
init();
return files.get(path);
}
@Override
public Collection<IMesonToolChainFile> getToolChainFiles() {
init();
return Collections.unmodifiableCollection(files.values());
}
@Override
public Collection<IMesonToolChainFile> getToolChainFilesMatching(Map<String, String> properties) {
List<IMesonToolChainFile> matches = new ArrayList<>();
for (IMesonToolChainFile file : getToolChainFiles()) {
boolean match = true;
for (Entry<String, String> entry : properties.entrySet()) {
if (!entry.getValue().equals(file.getProperty(entry.getKey()))) {
match = false;
break;
}
}
if (match) {
matches.add(file);
}
}
return matches;
}
@Override
public IMesonToolChainFile getToolChainFileFor(IToolChain toolchain) {
String id = toolchain.getId();
for (IMesonToolChainFile file : getToolChainFiles()) {
if (id.equals(file.getProperty(MesonBuildConfiguration.TOOLCHAIN_ID))) {
return file;
}
}
return null;
}
@Override
public void addListener(IMesonToolChainListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(IMesonToolChainListener listener) {
listeners.remove(listener);
}
private void fireEvent(MesonToolChainEvent event) {
for (IMesonToolChainListener listener : listeners) {
SafeRunner.run(new ISafeRunnable() {
@Override
public void run() throws Exception {
listener.handleCMakeToolChainEvent(event);
}
@Override
public void handleException(Throwable exception) {
Activator.log(exception);
}
});
}
}
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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
*
* Red Hat Inc. - initial version
*******************************************************************************/
package org.eclipse.cdt.internal.meson.core;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.meson.core.messages"; //$NON-NLS-1$
public static String MesonBuildConfiguration_Building;
public static String MesonBuildConfiguration_BuildingIn;
public static String MesonBuildConfiguration_BuildingComplete;
public static String MesonBuildConfiguration_Cleaning;
public static String MesonBuildConfiguration_RunningMeson;
public static String MesonBuildConfiguration_RunningMesonFailure;
public static String MesonBuildConfiguration_RunningNinjaFailure;
public static String MesonBuildConfiguration_NoToolchainFile;
public static String MesonBuildConfiguration_ProcCompCmds;
public static String MesonBuildConfiguration_ProcCompJson;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,21 @@
################################################################################
# Copyright (c) 2018 Red Hat Inc. 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
#
# Red Hat Inc. - initial implementation
################################################################################
MesonBuildConfiguration_Building=Building %s
MesonBuildConfiguration_BuildingIn=Building in: %s\n
MesonBuildConfiguration_BuildingComplete=Build complete: %s\n
MesonBuildConfiguration_Cleaning=Cleaning %s
MesonBuildConfiguration_RunningMeson=Running meson
MesonBuildConfiguration_ProcCompCmds=Processing compile commands %s
MesonBuildConfiguration_ProcCompJson=Processing compile_commands.json
MesonBuildConfiguration_NoToolchainFile=No toolchain file found for this target.
MesonBuildConfiguration_RunningMesonFailure=Failure running meson: %s
MesonBuildConfiguration_RunningNinjaFailure=Failure running ninja: %s

View file

@ -0,0 +1,172 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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
*
* Red Hat Inc. - initial version
*******************************************************************************/
package org.eclipse.cdt.meson.core;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Activator implements BundleActivator {
private static BundleContext context;
//The shared instance.
private static Activator plugin;
private ResourceBundle resourceBundle;
public static final String PLUGIN_ID = "org.eclipse.cdt.meson.core"; //$NON-NLS-1$
public Activator() {
Assert.isTrue(plugin == null);
plugin = this;
try {
resourceBundle = ResourceBundle.getBundle(PLUGIN_ID + ".Resources"); //$NON-NLS-1$
} catch (MissingResourceException x) {
resourceBundle = null;
}
}
public static String getPluginId() {
return PLUGIN_ID;
}
public static String getUniqueIdentifier() {
if (getDefault() == null) {
// If the default instance is not yet initialized,
// return a static identifier. This identifier must
// match the plugin id defined in plugin.xml
return PLUGIN_ID;
}
return context.getBundle().getSymbolicName();
}
public Bundle getBundle() {
return context.getBundle();
}
/**
* Returns the shared instance.
*/
public static Activator getDefault() {
return plugin;
}
/**
* Return the OSGi service with the given service interface.
*
* @param service service interface
* @return the specified service or null if it's not registered
* @since 1.5
*/
public static <T> T getService(Class<T> service) {
if (context != null) {
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
return null;
}
public static void error(String message, Throwable cause) {
log(errorStatus(message, cause));
}
public static IStatus errorStatus(String message, Throwable cause) {
return new Status(IStatus.ERROR, PLUGIN_ID, message, cause);
}
/**
* Returns the string from the plugin's resource bundle,
* or 'key' if not found.
*
* @param key the message key
* @return the resource bundle message
*/
public static String getResourceString(String key) {
ResourceBundle bundle = Activator.getDefault().getResourceBundle();
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
return key;
}
}
/**
* Returns the string from the plugin's resource bundle,
* or 'key' if not found.
*
* @param key the message key
* @param args an array of substituition strings
* @return the resource bundle message
*/
public static String getFormattedString(String key, String[] args) {
return MessageFormat.format(getResourceString(key), (Object[])args);
}
/**
* Returns the plugin's resource bundle,
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
public static void log(IStatus status) {
ResourcesPlugin.getPlugin().getLog().log(status);
}
public static void logErrorMessage(String message) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
}
public static void log(Throwable e) {
if (e instanceof InvocationTargetException)
e = ((InvocationTargetException) e).getTargetException();
IStatus status = null;
if (e instanceof CoreException)
status = ((CoreException) e).getStatus();
else
status = new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.OK, e.getMessage(), e);
log(status);
}
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
}
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
plugin = null;
}
}

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.core;
public interface IMesonConstants {
public static final String MESON_ARGUMENTS = "meson.arguments"; //$NON-NLS-1$
public static final String MESON_ENV = "meson.environment"; //$NON-NLS-1$
public static final String MESON_ENV_SEPARATOR = "|"; //$NON-NLS-1$
String MESON_GENERATOR = "meson.generator"; //$NON-NLS-1$
String BUILD_COMMAND = "meson.command.build"; //$NON-NLS-1$
String CLEAN_COMMAND = "meson.command.clean"; //$NON-NLS-1$
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Red Hat Inc. - modified for use with Meson builder
*******************************************************************************/
package org.eclipse.cdt.meson.core;
import java.nio.file.Path;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.core.runtime.CoreException;
/**
* A toolchain file.
*
* @noimplement
* @noextend
*/
public interface IMesonToolChainFile {
Path getPath();
String getProperty(String key);
void setProperty(String key, String value);
IToolChain getToolChain() throws CoreException;
}

View file

@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Red Hat Inc. - modified for use with Meson builder
*******************************************************************************/
package org.eclipse.cdt.meson.core;
/**
* Listener for toolchain events.
*/
public interface IMesonToolChainListener {
void handleCMakeToolChainEvent(MesonToolChainEvent event);
}

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Red Hat Inc. - modified for use with Meson builder
*******************************************************************************/
package org.eclipse.cdt.meson.core;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Map;
import org.eclipse.cdt.core.build.IToolChain;
/**
* Manages toolchain files for Meson.
*
* @noimplement
* @noextend
*/
public interface IMesonToolChainManager {
IMesonToolChainFile newToolChainFile(Path path);
void addToolChainFile(IMesonToolChainFile file);
void removeToolChainFile(IMesonToolChainFile file);
IMesonToolChainFile getToolChainFile(Path path);
Collection<IMesonToolChainFile> getToolChainFilesMatching(Map<String, String> properties);
IMesonToolChainFile getToolChainFileFor(IToolChain toolchain);
Collection<IMesonToolChainFile> getToolChainFiles();
void addListener(IMesonToolChainListener listener);
void removeListener(IMesonToolChainListener listener);
}

View file

@ -0,0 +1,16 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.meson.core;
public interface IMesonToolChainProvider {
void init(IMesonToolChainManager manager);
}

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2015, 2018 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
*
* Red Hat Inc. - modified for use in Meson build plug-in
*******************************************************************************/
package org.eclipse.cdt.meson.core;
import org.eclipse.cdt.core.build.CBuilder;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
public class MesonNature implements IProjectNature {
public static final String ID = Activator.getPluginId() + ".mesonNature"; //$NON-NLS-1$
private IProject project;
public static void setupBuilder(IProjectDescription projDesc) throws CoreException {
ICommand command = projDesc.newCommand();
CBuilder.setupBuilder(command);
projDesc.setBuildSpec(new ICommand[] { command });
}
@Override
public void configure() throws CoreException {
IProjectDescription projDesc = project.getDescription();
setupBuilder(projDesc);
project.setDescription(projDesc, new NullProgressMonitor());
}
@Override
public void deconfigure() throws CoreException {
}
@Override
public IProject getProject() {
return project;
}
@Override
public void setProject(IProject project) {
this.project = project;
}
}

View file

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2015, 2018 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
*
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.meson.core;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.build.CBuilder;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.tools.templates.freemarker.FMProjectGenerator;
import org.eclipse.tools.templates.freemarker.SourceRoot;
import org.eclipse.tools.templates.freemarker.TemplateManifest;
import org.osgi.framework.Bundle;
public class MesonProjectGenerator extends FMProjectGenerator {
public MesonProjectGenerator(String manifestFile) {
super(manifestFile);
}
@Override
protected void initProjectDescription(IProjectDescription description) {
description
.setNatureIds(
new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, MesonNature.ID });
ICommand command = description.newCommand();
CBuilder.setupBuilder(command);
description.setBuildSpec(new ICommand[] { command });
}
@Override
public Bundle getSourceBundle() {
return Activator.getDefault().getBundle();
}
@Override
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
super.generate(model, monitor);
List<IPathEntry> entries = new ArrayList<>();
IProject project = getProject();
// Create the source and output folders
IFolder buildFolder = getProject().getFolder("build"); //$NON-NLS-1$
TemplateManifest manifest = getManifest();
if (manifest != null) {
List<SourceRoot> srcRoots = getManifest().getSrcRoots();
if (srcRoots != null && !srcRoots.isEmpty()) {
for (SourceRoot srcRoot : srcRoots) {
IFolder sourceFolder = project.getFolder(srcRoot.getDir());
if (!sourceFolder.exists()) {
sourceFolder.create(true, true, monitor);
}
entries.add(CoreModel.newSourceEntry(sourceFolder.getFullPath(),
new IPath[] { buildFolder.getFullPath() }));
}
} else {
entries.add(CoreModel.newSourceEntry(getProject().getFullPath()));
}
}
entries.add(CoreModel.newOutputEntry(buildFolder.getFullPath(), // $NON-NLS-1$
new IPath[] {})); //$NON-NLS-1$
CoreModel.getDefault().create(project).setRawPathEntries(entries.toArray(new IPathEntry[entries.size()]),
monitor);
}
}

View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Red Hat Inc. - modified for use with Meson builder
*******************************************************************************/
package org.eclipse.cdt.meson.core;
/**
* Event occured with Meson ToolChain Files, either added or removed.
*/
public class MesonToolChainEvent {
/**
* ToolChain file has been added.
*/
public static final int ADDED = 1;
/**
* ToolChain File has been removed.
*/
public static final int REMOVED = 2;
private final int type;
private final IMesonToolChainFile toolChainFile;
public MesonToolChainEvent(int type, IMesonToolChainFile toolChainFile) {
this.type = type;
this.toolChainFile = toolChainFile;
}
public int getType() {
return type;
}
public IMesonToolChainFile getToolChainFile() {
return toolChainFile;
}
}

View file

@ -0,0 +1,7 @@
// Simple Hello World program
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World\n");
return 0;
}

View file

@ -0,0 +1,7 @@
<templateManifest>
<file src="/templates/simple/meson.build"
dest="/${projectName}/meson.build"/>
<file src="/templates/simple/main.c"
dest="/${projectName}/${projectName}.c"
open="true"/>
</templateManifest>

View file

@ -0,0 +1,3 @@
project('${projectName}', 'c')
executable('${projectName}', '${projectName}.c')

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.meson.ui</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,22 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.meson.ui;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: %vendorName
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Activator: org.eclipse.cdt.meson.ui.Activator
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.13.0",
org.eclipse.ui;bundle-version="3.109.0",
org.eclipse.cdt.meson.core;bundle-version="1.0.0",
org.eclipse.tools.templates.core;bundle-version="1.1.0",
org.eclipse.tools.templates.ui;bundle-version="1.1.1",
org.eclipse.ui.ide;bundle-version="3.13.1",
org.eclipse.tools.templates.freemarker;bundle-version="1.0.0",
org.eclipse.cdt.core;bundle-version="6.4.0",
org.eclipse.core.resources;bundle-version="3.12.0",
org.eclipse.debug.core;bundle-version="3.11.0",
org.eclipse.cdt.launch;bundle-version="9.2.0",
org.eclipse.debug.ui;bundle-version="3.12.50"

View file

@ -0,0 +1,26 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 22, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, "Program" will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party ("Redistributor") and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
<p>The file: icons/meson-logo.png is made available under the Apache Software License 2.0
(available at http://www.apache.org/licenses/LICENSE-2.0).
</body></html>

View file

@ -0,0 +1,8 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
icons/,\
plugin.xml,\
plugin.properties,\
about.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1,9 @@
###############################################################################
# Copyright (c) 2018 Red Hat Inc. 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
###############################################################################
meson.preferences.name = Meson

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.ui.propertyPages">
<page
class="org.eclipse.cdt.meson.ui.properties.MesonPropertyPage"
id="org.eclipse.cdt.meson.ui.properties.mesonPropertyPage"
name="Meson">
<enabledWhen>
<and>
<instanceof
value="org.eclipse.core.resources.IProject">
</instanceof>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.cdt.meson.core.mesonNature">
</test>
</and>
</enabledWhen>
</page>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
category="org.eclipse.cdt.ui.preferences.CPluginPreferencePage"
class="org.eclipse.cdt.internal.meson.ui.MesonPreferencePage"
id="org.eclipse.cdt.meson.ui.page1"
name="%meson.preferences.name">
</page>
</extension>
<extension
point="org.eclipse.tools.templates.ui.templates">
<tag
id="org.eclipse.cdt.meson.ui.tag"
label="Meson">
</tag>
<template
icon="icons/meson-logo.png"
id="org.eclipse.cdt.meson.ui.newProjectTemplate"
label="Meson Project"
wizard="org.eclipse.cdt.internal.meson.ui.NewMesonProjectWizard">
<description>
A Meson project with a Hello World executable to get started.
</description>
<tagReference
id="org.eclipse.cdt.ui.cdtTag">
</tagReference>
<tagReference
id="org.eclipse.cdt.meson.ui.tag">
</tagReference>
</template>
<template
icon="icons/meson-logo.png"
id="org.eclipse.cdt.meson.ui.emptyProjectTemplate"
label="Empty or Existing Meson Project"
wizard="org.eclipse.cdt.internal.meson.ui.EmptyMesonProjectWizard">
<description>
Create a Meson project with no files. Can be used to create one over existing content.
</description>
<tagReference
id="org.eclipse.cdt.ui.cdtTag">
</tagReference>
<tagReference
id="org.eclipse.cdt.meson.ui.tag">
</tagReference>
</template>
</extension>
<extension
point="org.eclipse.cdt.launch.coreBuildTab">
<provider
nature="org.eclipse.cdt.meson.core.mesonNature"
priority="10"
tabClass="org.eclipse.cdt.internal.meson.ui.MesonBuildTab">
</provider>
</extension>
</plugin>

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import org.eclipse.cdt.meson.core.MesonProjectGenerator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tools.templates.core.IGenerator;
import org.eclipse.tools.templates.ui.TemplateWizard;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
public class EmptyMesonProjectWizard extends TemplateWizard {
private WizardNewProjectCreationPage mainPage;
@Override
public void addPages() {
mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$
@Override
public void createControl(Composite parent) {
super.createControl(parent);
createWorkingSetGroup((Composite) getControl(), getSelection(),
new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
Dialog.applyDialogFont(getControl());
}
};
mainPage.setTitle("New Meson Project"); //$NON-NLS-1$
mainPage.setDescription("Specify properties of new Meson project."); //$NON-NLS-1$
this.addPage(mainPage);
}
@Override
protected IGenerator getGenerator() {
MesonProjectGenerator generator = new MesonProjectGenerator(null);
generator.setProjectName(mainPage.getProjectName());
if (!mainPage.useDefaults()) {
generator.setLocationURI(mainPage.getLocationURI());
}
return generator;
}
}

View file

@ -0,0 +1,237 @@
/*******************************************************************************
* Copyright (c) 2017, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import java.util.Map;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.internal.meson.core.MesonBuildConfigurationProvider;
import org.eclipse.cdt.launch.ui.corebuild.CommonBuildTab;
import org.eclipse.cdt.meson.core.IMesonConstants;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class MesonBuildTab extends CommonBuildTab {
private Button unixGenButton;
private Button ninjaGenButton;
private Text mesonArgsText;
private Text buildCommandText;
private Text cleanCommandText;
@Override
protected String getBuildConfigProviderId() {
return MesonBuildConfigurationProvider.ID;
}
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout());
setControl(comp);
Control tcControl = createToolchainSelector(comp);
tcControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Group mesonGroup = new Group(comp, SWT.NONE);
mesonGroup.setText(Messages.MesonBuildTab_Settings);
mesonGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
mesonGroup.setLayout(new GridLayout());
Label label = new Label(mesonGroup, SWT.NONE);
label.setText(Messages.MesonBuildTab_Generator);
Composite genComp = new Composite(mesonGroup, SWT.BORDER);
genComp.setLayout(new GridLayout(2, true));
unixGenButton = new Button(genComp, SWT.RADIO);
unixGenButton.setText(Messages.MesonBuildTab_UnixMakefiles);
unixGenButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
ninjaGenButton = new Button(genComp, SWT.RADIO);
ninjaGenButton.setText(Messages.MesonBuildTab_Ninja);
ninjaGenButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
label = new Label(mesonGroup, SWT.NONE);
label.setText(Messages.MesonBuildTab_MesonArgs);
mesonArgsText = new Text(mesonGroup, SWT.BORDER);
mesonArgsText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
mesonArgsText.addModifyListener(e -> updateLaunchConfigurationDialog());
label = new Label(mesonGroup, SWT.NONE);
label.setText(Messages.MesonBuildTab_BuildCommand);
buildCommandText = new Text(mesonGroup, SWT.BORDER);
buildCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
buildCommandText.addModifyListener(e -> updateLaunchConfigurationDialog());
label = new Label(mesonGroup, SWT.NONE);
label.setText(Messages.MesonBuildTab_CleanCommand);
cleanCommandText = new Text(mesonGroup, SWT.BORDER);
cleanCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
cleanCommandText.addModifyListener(e -> updateLaunchConfigurationDialog());
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
// TODO
}
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
super.initializeFrom(configuration);
ICBuildConfiguration buildConfig = getBuildConfiguration();
String generator = buildConfig.getProperty(IMesonConstants.MESON_GENERATOR);
updateGeneratorButtons(generator);
String mesonArgs = buildConfig.getProperty(IMesonConstants.MESON_ARGUMENTS);
if (mesonArgs != null) {
mesonArgsText.setText(mesonArgs);
} else {
mesonArgsText.setText(""); //$NON-NLS-1$
}
String buildCommand = buildConfig.getProperty(IMesonConstants.BUILD_COMMAND);
if (buildCommand != null) {
buildCommandText.setText(buildCommand);
} else {
buildCommandText.setText(""); //$NON-NLS-1$
}
String cleanCommand = buildConfig.getProperty(IMesonConstants.CLEAN_COMMAND);
if (cleanCommand != null) {
cleanCommandText.setText(buildCommand);
} else {
cleanCommandText.setText(""); //$NON-NLS-1$
}
}
private void updateGeneratorButtons(String generator) {
if (generator == null || generator.equals("Ninja")) { //$NON-NLS-1$
ninjaGenButton.setSelection(true);
} else {
unixGenButton.setSelection(true);
}
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
super.performApply(configuration);
ICBuildConfiguration buildConfig = getBuildConfiguration();
buildConfig.setProperty(IMesonConstants.MESON_GENERATOR,
ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"); //$NON-NLS-1$ //$NON-NLS-2$
String mesonArgs = mesonArgsText.getText().trim();
if (!mesonArgs.isEmpty()) {
buildConfig.setProperty(IMesonConstants.MESON_ARGUMENTS, mesonArgs);
} else {
buildConfig.removeProperty(IMesonConstants.MESON_ARGUMENTS);
}
String buildCommand = buildCommandText.getText().trim();
if (!buildCommand.isEmpty()) {
buildConfig.setProperty(IMesonConstants.BUILD_COMMAND, buildCommand);
} else {
buildConfig.removeProperty(IMesonConstants.BUILD_COMMAND);
}
String cleanCommand = cleanCommandText.getText().trim();
if (!cleanCommand.isEmpty()) {
buildConfig.setProperty(IMesonConstants.CLEAN_COMMAND, cleanCommand);
} else {
buildConfig.removeProperty(IMesonConstants.CLEAN_COMMAND);
}
}
@Override
protected void saveProperties(Map<String, String> properties) {
super.saveProperties(properties);
properties.put(IMesonConstants.MESON_GENERATOR,
ninjaGenButton.getSelection() ? "Ninja" : "Unix Makefiles"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put(IMesonConstants.MESON_ARGUMENTS, mesonArgsText.getText().trim());
properties.put(IMesonConstants.BUILD_COMMAND, buildCommandText.getText().trim());
properties.put(IMesonConstants.CLEAN_COMMAND, cleanCommandText.getText().trim());
}
@Override
protected void restoreProperties(Map<String, String> properties) {
super.restoreProperties(properties);
String gen = properties.get(IMesonConstants.MESON_GENERATOR);
if (gen != null) {
switch (gen) {
case "Ninja": //$NON-NLS-1$
ninjaGenButton.setSelection(true);
unixGenButton.setSelection(false);
break;
case "Unix Makefiles": //$NON-NLS-1$
ninjaGenButton.setSelection(false);
unixGenButton.setSelection(true);
break;
}
}
String mesonArgs = properties.get(IMesonConstants.MESON_ARGUMENTS);
if (mesonArgs != null) {
mesonArgsText.setText(mesonArgs);
} else {
mesonArgsText.setText(""); //$NON-NLS-1$
}
String buildCmd = properties.get(IMesonConstants.BUILD_COMMAND);
if (buildCmd != null) {
buildCommandText.setText(buildCmd);
} else {
buildCommandText.setText(""); //$NON-NLS-1$
}
String cleanCmd = properties.get(IMesonConstants.CLEAN_COMMAND);
if (cleanCmd != null) {
cleanCommandText.setText(cleanCmd);
} else {
cleanCommandText.setText(""); //$NON-NLS-1$
}
}
@Override
public String getName() {
return Messages.MesonBuildTab_Meson;
}
}

View file

@ -0,0 +1,196 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.cdt.meson.core.IMesonToolChainManager;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
public class MesonPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private IMesonToolChainManager manager;
private Table filesTable;
private Button removeButton;
private Map<Path, IMesonToolChainFile> filesToAdd = new HashMap<>();
private Map<Path, IMesonToolChainFile> filesToRemove = new HashMap<>();
@Override
public void init(IWorkbench workbench) {
manager = Activator.getService(IMesonToolChainManager.class);
}
@Override
protected Control createContents(Composite parent) {
Composite control = new Composite(parent, SWT.NONE);
control.setLayout(new GridLayout());
Group filesGroup = new Group(control, SWT.NONE);
filesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
filesGroup.setText(Messages.MesonPreferencePage_Files);
filesGroup.setLayout(new GridLayout(2, false));
Composite filesComp = new Composite(filesGroup, SWT.NONE);
filesComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
filesTable = new Table(filesComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
filesTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
filesTable.setHeaderVisible(true);
filesTable.setLinesVisible(true);
filesTable.addListener(SWT.Selection, e -> {
TableItem[] items = filesTable.getSelection();
removeButton.setEnabled(items.length > 0);
});
TableColumn pathColumn = new TableColumn(filesTable, SWT.NONE);
pathColumn.setText(Messages.MesonPreferencePage_Path);
TableColumn tcColumn = new TableColumn(filesTable, SWT.NONE);
tcColumn.setText(Messages.MesonPreferencePage_Toolchain);
TableColumnLayout tableLayout = new TableColumnLayout();
tableLayout.setColumnData(pathColumn, new ColumnWeightData(50, 350, true));
tableLayout.setColumnData(tcColumn, new ColumnWeightData(50, 350, true));
filesComp.setLayout(tableLayout);
Composite buttonsComp = new Composite(filesGroup, SWT.NONE);
buttonsComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
buttonsComp.setLayout(new GridLayout());
Button addButton = new Button(buttonsComp, SWT.PUSH);
addButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
addButton.setText(Messages.MesonPreferencePage_Add);
addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
NewMesonToolChainFileWizard wizard = new NewMesonToolChainFileWizard();
WizardDialog dialog = new WizardDialog(getShell(), wizard);
if (dialog.open() == Window.OK) {
IMesonToolChainFile file = wizard.getNewFile();
if (filesToRemove.containsKey(file.getPath())) {
filesToRemove.remove(file.getPath());
} else {
filesToAdd.put(file.getPath(), file);
}
updateTable();
}
}
});
removeButton = new Button(buttonsComp, SWT.PUSH);
removeButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
removeButton.setText(Messages.MesonPreferencePage_Remove);
removeButton.setEnabled(false);
removeButton.addListener(SWT.Selection, e -> {
if (MessageDialog.openConfirm(getShell(), Messages.MesonPreferencePage_ConfirmRemoveTitle,
Messages.MesonPreferencePage_ConfirmRemoveDesc)) {
for (TableItem item : filesTable.getSelection()) {
IMesonToolChainFile file = (IMesonToolChainFile) item.getData();
if (filesToAdd.containsKey(file.getPath())) {
filesToAdd.remove(file.getPath());
} else {
filesToRemove.put(file.getPath(), file);
}
updateTable();
}
}
});
updateTable();
return control;
}
private void updateTable() {
List<IMesonToolChainFile> sorted = new ArrayList<>(getFiles().values());
Collections.sort(sorted, (o1, o2) -> o1.getPath().toString().compareToIgnoreCase(o2.getPath().toString()));
filesTable.removeAll();
for (IMesonToolChainFile file : sorted) {
TableItem item = new TableItem(filesTable, SWT.NONE);
item.setText(0, file.getPath().toString());
try {
IToolChain tc = file.getToolChain();
if (tc != null) {
item.setText(1, tc.getName());
}
} catch (CoreException e) {
Activator.log(e.getStatus());
}
item.setData(file);
}
}
private Map<Path, IMesonToolChainFile> getFiles() {
Map<Path, IMesonToolChainFile> files = new HashMap<>();
for (IMesonToolChainFile file : manager.getToolChainFiles()) {
files.put(file.getPath(), file);
}
for (IMesonToolChainFile file : filesToAdd.values()) {
files.put(file.getPath(), file);
}
for (IMesonToolChainFile file : filesToRemove.values()) {
files.remove(file.getPath());
}
return files;
}
@Override
public boolean performOk() {
for (IMesonToolChainFile file : filesToAdd.values()) {
manager.addToolChainFile(file);
}
for (IMesonToolChainFile file : filesToRemove.values()) {
manager.removeToolChainFile(file);
}
filesToAdd.clear();
filesToRemove.clear();
return true;
}
}

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
public static String MesonBuildTab_BuildCommand;
public static String MesonBuildTab_CleanCommand;
public static String MesonBuildTab_Meson;
public static String MesonBuildTab_MesonArgs;
public static String MesonBuildTab_Generator;
public static String MesonBuildTab_Ninja;
public static String MesonBuildTab_NoneAvailable;
public static String MesonBuildTab_Settings;
public static String MesonBuildTab_Toolchain;
public static String MesonBuildTab_UnixMakefiles;
public static String MesonPreferencePage_Add;
public static String MesonPreferencePage_ConfirmRemoveDesc;
public static String MesonPreferencePage_ConfirmRemoveTitle;
public static String MesonPreferencePage_Files;
public static String MesonPreferencePage_Path;
public static String MesonPreferencePage_Remove;
public static String MesonPreferencePage_Toolchain;
public static String MesonPropertyPage_FailedToStartMesonGui_Body;
public static String MesonPropertyPage_FailedToStartMesonGui_Title;
public static String MesonPropertyPage_LaunchMesonGui;
public static String NewMesonProjectWizard_Description;
public static String NewMesonProjectWizard_PageTitle;
public static String NewMesonProjectWizard_WindowTitle;
public static String NewMesonToolChainFilePage_Browse;
public static String NewMesonToolChainFilePage_NoPath;
public static String NewMesonToolChainFilePage_Path;
public static String NewMesonToolChainFilePage_Select;
public static String NewMesonToolChainFilePage_Title;
public static String NewMesonToolChainFilePage_Toolchain;
static {
// initialize resource bundle
NLS.initializeMessages("org.eclipse.cdt.internal.meson.ui.messages", Messages.class); //$NON-NLS-1$
}
private Messages() {
}
}

View file

@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import org.eclipse.cdt.meson.core.MesonProjectGenerator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tools.templates.core.IGenerator;
import org.eclipse.tools.templates.ui.TemplateWizard;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
public class NewMesonProjectWizard extends TemplateWizard {
private WizardNewProjectCreationPage mainPage;
@Override
public void setContainer(IWizardContainer wizardContainer) {
super.setContainer(wizardContainer);
setWindowTitle(Messages.NewMesonProjectWizard_WindowTitle);
}
@Override
public void addPages() {
mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$
@Override
public void createControl(Composite parent) {
super.createControl(parent);
createWorkingSetGroup((Composite) getControl(), getSelection(),
new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
Dialog.applyDialogFont(getControl());
}
};
mainPage.setTitle(Messages.NewMesonProjectWizard_PageTitle);
mainPage.setDescription(Messages.NewMesonProjectWizard_Description);
this.addPage(mainPage);
}
@Override
protected IGenerator getGenerator() {
MesonProjectGenerator generator = new MesonProjectGenerator("templates/simple/manifest.xml"); //$NON-NLS-1$
generator.setProjectName(mainPage.getProjectName());
if (!mainPage.useDefaults()) {
generator.setLocationURI(mainPage.getLocationURI());
}
return generator;
}
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import java.nio.file.Paths;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.cdt.meson.core.IMesonToolChainManager;
import org.eclipse.cdt.meson.core.Activator;
import org.eclipse.cdt.internal.meson.core.MesonBuildConfiguration;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class NewMesonToolChainFilePage extends WizardPage {
private Text pathText;
private Combo tcCombo;
private IToolChain[] toolchains;
public NewMesonToolChainFilePage() {
super("NewMesonToolChainFilePage", Messages.NewMesonToolChainFilePage_Title, null); //$NON-NLS-1$
}
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
comp.setLayout(new GridLayout(2, false));
Label pathLabel = new Label(comp, SWT.NONE);
pathLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
pathLabel.setText(Messages.NewMesonToolChainFilePage_Path);
Composite pathComp = new Composite(comp, SWT.NONE);
pathComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = layout.marginWidth = 0;
pathComp.setLayout(layout);
pathText = new Text(pathComp, SWT.BORDER);
pathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
pathText.addModifyListener(e -> validate());
Button pathButton = new Button(pathComp, SWT.PUSH);
pathButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
pathButton.setText(Messages.NewMesonToolChainFilePage_Browse);
pathButton.addListener(SWT.Selection, e -> {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setText(Messages.NewMesonToolChainFilePage_Select);
String path = dialog.open();
if (path != null) {
pathText.setText(path);
}
});
Label tcLabel = new Label(comp, SWT.NONE);
tcLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
tcLabel.setText(Messages.NewMesonToolChainFilePage_Toolchain);
tcCombo = new Combo(comp, SWT.READ_ONLY);
tcCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
try {
IToolChainManager tcManager = Activator.getService(IToolChainManager.class);
toolchains = tcManager.getAllToolChains().toArray(new IToolChain[0]);
for (IToolChain tc : toolchains) {
tcCombo.add(tc.getName());
}
tcCombo.select(0);
} catch (CoreException e) {
Activator.log(e.getStatus());
}
setControl(comp);
validate();
}
private void validate() {
setPageComplete(false);
String path = pathText.getText();
if (path.isEmpty()) {
setErrorMessage(Messages.NewMesonToolChainFilePage_NoPath);
return;
}
setPageComplete(true);
setErrorMessage(null);
}
public IMesonToolChainFile getNewFile() {
IMesonToolChainManager manager = Activator.getService(IMesonToolChainManager.class);
IMesonToolChainFile file = manager.newToolChainFile(Paths.get(pathText.getText()));
IToolChain tc = toolchains[tcCombo.getSelectionIndex()];
file.setProperty(MesonBuildConfiguration.TOOLCHAIN_TYPE, tc.getTypeId());
file.setProperty(MesonBuildConfiguration.TOOLCHAIN_ID, tc.getId());
return file;
}
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2016, 2018 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
*
* Contributors:
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.internal.meson.ui;
import org.eclipse.cdt.meson.core.IMesonToolChainFile;
import org.eclipse.jface.wizard.Wizard;
public class NewMesonToolChainFileWizard extends Wizard {
private IMesonToolChainFile newFile;
private NewMesonToolChainFilePage page;
@Override
public void addPages() {
page = new NewMesonToolChainFilePage();
addPage(page);
}
@Override
public boolean performFinish() {
newFile = page.getNewFile();
return true;
}
public IMesonToolChainFile getNewFile() {
return newFile;
}
}

View file

@ -0,0 +1,39 @@
################################################################################
# Copyright (c) 2018 Red Hat Inc. 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:
# Red Hat Inc. - initial implementation
################################################################################
MesonBuildTab_BuildCommand=Build command
MesonBuildTab_CleanCommand=Clean command
MesonBuildTab_Meson=Meson
MesonBuildTab_MesonArgs=Additional Meson arguments:
MesonBuildTab_Generator=Generator
MesonBuildTab_Ninja=Ninja
MesonBuildTab_NoneAvailable=No Toolchains Available for this Target
MesonBuildTab_Settings=Meson Settings
MesonBuildTab_Toolchain=Toolchain
MesonBuildTab_UnixMakefiles=Unix Makefiles
MesonPreferencePage_Add=Add...
MesonPreferencePage_ConfirmRemoveDesc=Do you wish to deregister the selected files?
MesonPreferencePage_ConfirmRemoveTitle=Deregister Meson ToolChain File
MesonPreferencePage_Files=Toolchain Files
MesonPreferencePage_Path=Toolchain File
MesonPreferencePage_Remove=Remove
MesonPreferencePage_Toolchain=Toolchain
MesonPropertyPage_FailedToStartMesonGui_Body=Failed to run the Meson GUI:
MesonPropertyPage_FailedToStartMesonGui_Title=Failed to run Meson GUI
MesonPropertyPage_LaunchMesonGui=Launch Meson GUI...
NewMesonProjectWizard_Description=Specify properties of new Meson project.
NewMesonProjectWizard_PageTitle=New Meson Project
NewMesonProjectWizard_WindowTitle=New Meson Project
NewMesonToolChainFilePage_Browse=Browse...
NewMesonToolChainFilePage_NoPath=Please set the path to the Meson toolchain file.
NewMesonToolChainFilePage_Path=Path:
NewMesonToolChainFilePage_Select=Select location for Meson toolchain file
NewMesonToolChainFilePage_Title=New Meson ToolChain File
NewMesonToolChainFilePage_Toolchain=Toolchain:

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Activator extends AbstractUIPlugin {
private static Activator plugin;
public static final String PLUGIN_ID = "org.eclipse.cdt.meson.ui"; //$NON-NLS-1$
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
public static Activator getPlugin() {
return plugin;
}
public static IStatus errorStatus(String message, Throwable cause) {
return new Status(IStatus.ERROR, PLUGIN_ID, message, cause);
}
public static void log(IStatus status) {
plugin.getLog().log(status);
}
public static void log(Exception e) {
if (e instanceof CoreException) {
log(((CoreException) e).getStatus());
} else {
plugin.getLog().log(errorStatus(e.getLocalizedMessage(), e));
}
}
public static <T> T getService(Class<T> service) {
if (plugin != null) {
BundleContext context = plugin.getBundle().getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
return null;
}
}

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
public interface IMesonPropertyPageControl {
/**
* Get the value of the field
* @return field value
*/
String getFieldValue();
/**
* Get the name of the field to set for meson command
* @return field name
*/
String getFieldName();
/**
* Has the initial value changed
* @return
*/
boolean isValueChanged();
/**
* Is this field valid?
* @return
*/
boolean isValid();
/**
* Get the command line parameter if already configured
* @return String containing command-line for configured build dir
*/
public default String getConfiguredString() {
return "-D" + getFieldName() + "=" + getFieldValue(); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Get the command line parameter if never configured
* @return String containing command-line parm for configured build dir
*/
public default String getUnconfiguredString() {
// TODO Auto-generated method stub
return "--" + getFieldName() + "=" + getFieldValue(); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Get any error message for the control
* @return error message
*/
String getErrorMessage();
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.swt.widgets.Composite;
public class MesonPropertyArgs extends MesonPropertyText {
public MesonPropertyArgs(Composite composite, String name, String initialValue, String tooltip) {
super(composite, name, initialValue, tooltip);
}
@Override
public String getConfiguredString() {
// TODO Auto-generated method stub
return "-D" + getFieldName() + "='" + getFieldValue() + "'"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
public class MesonPropertyCheckbox implements IMesonPropertyPageControl {
private String name;
private boolean initialValue;
protected Button checkbox;
public MesonPropertyCheckbox(Composite composite, String name, boolean initialValue, String tooltip) {
this.name = name;
this.initialValue = initialValue;
checkbox = new Button(composite, SWT.CHECK);
GridData data = new GridData(GridData.FILL, GridData.FILL, true, false);
data.horizontalSpan = 2;
checkbox.setText(name);
checkbox.setLayoutData(data);
checkbox.setSelection(initialValue);
checkbox.setToolTipText(tooltip);
}
@Override
public String getFieldValue() {
return Boolean.toString(checkbox.getSelection());
}
@Override
public String getFieldName() {
return name;
}
@Override
public boolean isValueChanged() {
return checkbox.getSelection() != initialValue;
}
@Override
public boolean isValid() {
return true;
}
@Override
public String getErrorMessage() {
return null;
}
}

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
public class MesonPropertyCombo implements IMesonPropertyPageControl {
private String name;
private String initialValue;
private Combo combo;
public MesonPropertyCombo(Composite composite, String name, String[] values, String initialValue, String tooltip) {
this.name = name;
this.initialValue = initialValue;
Label label = new Label(composite, SWT.NONE);
label.setText(name);
label.setLayoutData(new GridData());
combo = new Combo(composite, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
GridData data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
combo.setLayoutData(data);
combo.setItems(values);
combo.setText(initialValue);
combo.setToolTipText(tooltip);
}
@Override
public String getFieldValue() {
return combo.getText();
}
@Override
public String getFieldName() {
return name;
}
@Override
public boolean isValueChanged() {
return !combo.getText().equals(initialValue);
}
@Override
public boolean isValid() {
return true;
}
@Override
public String getErrorMessage() {
return null;
}
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
public class MesonPropertyInteger extends MesonPropertyText {
@SuppressWarnings("unused")
private MesonPropertyPage page;
private String errorMessage;
public MesonPropertyInteger(Composite composite, MesonPropertyPage page, String name, String initialValue, String tooltip) {
super(composite, name, initialValue, tooltip);
this.page = page;
text.addModifyListener((e) -> {
if (isValid() != page.isValid()) {
page.update();
}
});
}
@Override
public boolean isValid() {
errorMessage = null;
try {
Integer.parseInt(getFieldValue());
return true;
} catch (NumberFormatException e) {
errorMessage = NLS.bind(Messages.MesonPropertyPage_not_an_integer, getFieldName());
}
return false;
}
@Override
public String getErrorMessage() {
return errorMessage;
}
}

View file

@ -0,0 +1,459 @@
/*******************************************************************************
* Copyright (c) 2016,2018 IAR Systems AB
* 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:
* IAR Systems - initial API and implementation
* Red Hat Inc. - modified for use in Meson build
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncherManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.CBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.meson.core.IMesonConstants;
import org.eclipse.cdt.meson.ui.Activator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.dialogs.PropertyPage;
/**
* Property page for CMake projects. The only thing we have here at the moment is a button
* to launch the CMake GUI configurator (cmake-qt-gui).
*
* We assume that the build directory is in project/build/configname, which is where
* the CMake project wizard puts it. We also assume that "cmake-gui" is in the user's
* PATH.
*/
public class MesonPropertyPage extends PropertyPage {
private IProject project;
private List<IMesonPropertyPageControl> componentList = new ArrayList<>();
private boolean configured;
private CBuildConfiguration buildConfig;
@Override
protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
composite.setLayout(new GridLayout(1, true));
project = (IProject) getElement();
String configName;
try {
buildConfig = ((CBuildConfiguration)project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class));
configName = ((CBuildConfiguration)project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class)).getName();
IPath sourceDir = project.getLocation();
String buildDir = project.getLocation().append("build").append(configName).toOSString(); //$NON-NLS-1$
IPath buildPath = new Path(buildDir).append("build.ninja"); //$NON-NLS-1$
configured = buildPath.toFile().exists();
if (configured) {
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class));
Process p = launcher.execute(new Path("meson"), new String[] { "configure", buildDir}, new String[0], sourceDir, new NullProgressMonitor());
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
int rc = -1;
try {
if (launcher.waitAndRead(stdout, stderr, new NullProgressMonitor()) == ICommandLauncher.OK) {
p.waitFor();
}
rc = p.exitValue();
} catch (InterruptedException e) {
// ignore for now
}
if (rc == 0) {
componentList = parseConfigureOutput(stdout, composite);
}
} else {
Map<String, String> argMap = new HashMap<>();
String mesonArgs = buildConfig.getProperty(IMesonConstants.MESON_ARGUMENTS);
if (mesonArgs != null) {
String[] argStrings = mesonArgs.split("\\s+");
for (String argString : argStrings) {
String[] s = argString.split("=");
if (s.length == 2) {
argMap.put(s[0], s[1]);
} else {
argMap.put(argString, "true");
}
}
}
String defaultBuildType = "release";
if (configName.contains("debug")) { //$NON-NLS-1$
defaultBuildType = "debug"; //$NON-NLS-1$
}
componentList = defaultOptions(composite, argMap, defaultBuildType);
}
} catch (CoreException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
return composite;
}
public void update() {
setErrorMessage(null);
for (IMesonPropertyPageControl control : componentList) {
if (!control.isValid()) {
setValid(false);
setErrorMessage(control.getErrorMessage());
}
}
}
public enum ParseState {
INIT, GROUP, OPTION, OPTION_WITH_VALUES, ARGS
};
@Override
public boolean performOk() {
List<String> args = new ArrayList<>();
if (configured) {
args.add("configure"); //$NON-NLS-1$
for (IMesonPropertyPageControl control : componentList) {
if (control.isValueChanged()) {
args.add(control.getConfiguredString()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
if (args.size() == 1) {
return true;
}
try {
String configName = ((CBuildConfiguration)project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class)).getName();
IPath sourceDir = project.getLocation();
String buildDir = project.getLocation().append("build").append(configName).toOSString(); //$NON-NLS-1$
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class));
args.add(buildDir);
Process p = launcher.execute(new Path("meson"), args.toArray(new String[0]), new String[0], sourceDir, new NullProgressMonitor());
int rc = -1;
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(project);
try (OutputStream stdout = console.getOutputStream()) {
OutputStream stderr = stdout;
StringBuilder buf = new StringBuilder();
buf.append("meson");
for (String arg : args) {
buf.append(" "); //$NON-NLS-1$
buf.append(arg);
}
buf.append(System.lineSeparator());
stdout.write(buf.toString().getBytes());
stdout.flush();
try {
if (launcher.waitAndRead(stdout, stderr, new NullProgressMonitor()) == ICommandLauncher.OK) {
p.waitFor();
}
rc = p.exitValue();
stdout.write(NLS.bind(Messages.MesonPropertyPage_terminated_rc, rc).getBytes());
stdout.flush();
if (rc != 0) {
Display.getDefault().syncExec(() -> {
MessageDialog.openError(getShell(), null, Messages.MesonPropertyPage_configure_failed);
});
}
} catch (InterruptedException e) {
// ignore for now
}
} catch (IOException e2) {
Activator.log(e2);
return false;
}
} catch (CoreException e3) {
// TODO Auto-generated catch block
Activator.log(e3);
return false;
}
} else {
StringBuilder mesonargs = new StringBuilder();
for (IMesonPropertyPageControl control : componentList) {
System.out.println(control.getUnconfiguredString());
mesonargs.append(control.getUnconfiguredString());
mesonargs.append(" "); //$NON-NLS-1$
}
buildConfig.setProperty(IMesonConstants.MESON_ARGUMENTS, mesonargs.toString());
}
return true;
}
/**
* Parse output of meson configure call to determine options to show to user
* @param stdout - ByteArrayOutputStream containing output of command
* @param composite - Composite to add Controls to
* @return - list of Controls
*/
List<IMesonPropertyPageControl> parseConfigureOutput(ByteArrayOutputStream stdout, Composite composite) {
List<IMesonPropertyPageControl> controls = new ArrayList<>();
try {
String[] lines = stdout.toString(StandardCharsets.UTF_8.name()).split("\\r?\\n"); //$NON-NLS-1$
ParseState state = ParseState.INIT;
Pattern optionPattern = Pattern.compile(Messages.MesonPropertyPage_option_pattern);
Pattern optionWithValuesPattern = Pattern.compile(Messages.MesonPropertyPage_option_with_values_pattern);
Pattern optionLine = Pattern.compile("(\\w+)\\s+(\\w+)\\s+(.*)$"); //$NON-NLS-1$
Pattern optionWithValuesLine = Pattern.compile("(\\w+)\\s+(\\w+)\\s+\\[(\\w+)((,\\s+\\w+)*)\\]\\s+(.*)$");
Pattern compilerOrLinkerArgs = Pattern.compile(Messages.MesonPropertyPage_compiler_or_link_args);
Pattern argLine = Pattern.compile("(\\w+)\\s+\\[([^\\]]*)\\]"); //$NON-NLS-1$
Pattern groupPattern = Pattern.compile("(([^:]*)):"); //$NON-NLS-1$
String groupName = ""; //$NON-NLS-1$
Composite parent = composite;
for (String line : lines) {
line = line.trim();
switch (state) {
case INIT:
Matcher argMatcher = compilerOrLinkerArgs.matcher(line);
if (argMatcher.matches()) {
state = ParseState.ARGS;
Group group = new Group(composite, SWT.BORDER);
group.setLayout(new GridLayout(2, true));
group.setLayoutData(new GridData(GridData.FILL_BOTH));
group.setText(argMatcher.group(1));
parent = group;
} else {
Matcher groupMatcher = groupPattern.matcher(line);
if (groupMatcher.matches()) {
groupName = groupMatcher.group(1);
state = ParseState.GROUP;
}
parent = composite;
}
break;
case GROUP:
Matcher m = optionPattern.matcher(line);
if (m.matches()) {
state = ParseState.OPTION;
Group group = new Group(composite, SWT.BORDER);
group.setLayout(new GridLayout(2, true));
group.setLayoutData(new GridData(GridData.FILL_BOTH));
group.setText(groupName);
parent = group;
break;
}
m = optionWithValuesPattern.matcher(line);
if (m.matches()) {
state = ParseState.OPTION_WITH_VALUES;
Group group = new Group(composite, SWT.BORDER);
group.setLayout(new GridLayout(2, true));
group.setLayoutData(new GridData(GridData.FILL_BOTH));
group.setText(groupName);
parent = group;
}
break;
case ARGS:
Matcher m2 = argLine.matcher(line);
if (m2.matches()) {
String argName = m2.group(1);
String argValue = m2.group(2);
argValue = argValue.replaceAll("',", ""); //$NON-NLS-1$ //$NON-NLS-2$
argValue = argValue.replaceAll("'", ""); //$NON-NLS-1$ //$NON-NLS-2$
String argDescription = Messages.MesonPropertyPage_arg_description;
IMesonPropertyPageControl argControl = new MesonPropertyText(parent, argName, argValue, argDescription);
controls.add(argControl);
}
state = ParseState.INIT;
parent = composite;
break;
case OPTION:
Matcher m3 = optionLine.matcher(line);
if (line.startsWith("----")) { //$NON-NLS-1$
break;
}
if (line.isEmpty()) {
state = ParseState.INIT;
parent = composite;
break;
}
if (m3.matches()) {
String name = m3.group(1);
String value = m3.group(2);
String description = m3.group(3);
boolean isInteger = false;
try {
Integer.parseInt(value);
isInteger = true;
} catch (NumberFormatException e) {
// do nothing
}
if (isInteger) {
IMesonPropertyPageControl control = new MesonPropertyInteger(parent, this, name, value, description);
controls.add(control);
} else if (Messages.MesonPropertyPage_true.equals(value) ||
Messages.MesonPropertyPage_false.equals(value)) {
IMesonPropertyPageControl control = new MesonPropertyCheckbox(parent, name, Boolean.getBoolean(value), description);
controls.add(control);
} else {
IMesonPropertyPageControl control = new MesonPropertyText(parent, name, value, description);
controls.add(control);
}
}
break;
case OPTION_WITH_VALUES:
Matcher m4 = optionWithValuesLine.matcher(line);
if (line.startsWith("----")) { //$NON-NLS-1$
break;
}
if (line.isEmpty()) {
state = ParseState.INIT;
parent = composite;
break;
}
if (m4.matches()) {
String name = m4.group(1);
String value = m4.group(2);
String possibleValue = m4.group(3);
String extraValues = m4.group(4);
String description = m4.group(6);
String[] values = new String[] {possibleValue};
if (!extraValues.isEmpty()) {
values = extraValues.split(",\\s+");
values[0] = possibleValue;
}
IMesonPropertyPageControl control = new MesonPropertyCombo(parent, name, values, value, description);
controls.add(control);
}
break;
}
}
} catch (UnsupportedEncodingException e) {
return controls;
}
return controls;
}
/**
* Create list of options for initial meson call
* @param stdout - ByteArrayOutputStream containing output of command
* @param composite - Composite to add Controls to
* @return - list of Controls
*/
List<IMesonPropertyPageControl> defaultOptions(Composite composite, Map<String, String> argMap, String defaultBuildType) {
List<IMesonPropertyPageControl> controls = new ArrayList<>();
Group group = new Group(composite, SWT.BORDER);
group.setLayout(new GridLayout(2, true));
group.setLayoutData(new GridData(GridData.FILL_BOTH));
group.setText("Options");
IMesonPropertyPageControl prefix = new MesonPropertyText(group, "prefix", argMap.get("--prefix"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_prefix_tooltip);
controls.add(prefix);
IMesonPropertyPageControl libdir = new MesonPropertyText(group, "libdir", argMap.get("--libdir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_libdir_tooltip);
controls.add(libdir);
IMesonPropertyPageControl libexecdir = new MesonPropertyText(group, "libexecdir", argMap.get("--libexecdir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_libexecdir_tooltip);
controls.add(libexecdir);
IMesonPropertyPageControl bindir = new MesonPropertyText(group, "bindir", argMap.get("--bindir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_bindir_tooltip);
controls.add(bindir);
IMesonPropertyPageControl sbindir = new MesonPropertyText(group, "sbindir", argMap.get("--sbindir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_sbindir_tooltip);
controls.add(sbindir);
IMesonPropertyPageControl includedir = new MesonPropertyText(group, "includedir", argMap.get("--includedir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_includedir_tooltip);
controls.add(includedir);
IMesonPropertyPageControl datadir = new MesonPropertyText(group, "datadir", argMap.get("--datadir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_datadir_tooltip);
controls.add(datadir);
IMesonPropertyPageControl mandir = new MesonPropertyText(group, "mandir", argMap.get("--mandir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_mandir_tooltip);
controls.add(mandir);
IMesonPropertyPageControl infodir = new MesonPropertyText(group, "infodir", argMap.get("--infodir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_infodir_tooltip);
controls.add(infodir);
IMesonPropertyPageControl localedir = new MesonPropertyText(group, "localedir", argMap.get("--localedir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_localedir_tooltip);
controls.add(localedir);
IMesonPropertyPageControl sysconfdir = new MesonPropertyText(group, "sysconfdir", argMap.get("--sysconfdir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_sysconfdir_tooltip);
controls.add(sysconfdir);
IMesonPropertyPageControl localstatedir = new MesonPropertyText(group, "localstatedir", argMap.get("--localstatedir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_localstatedir_tooltip);
controls.add(localstatedir);
IMesonPropertyPageControl sharedstatedir = new MesonPropertyText(group, "sharedstatedir", argMap.get("--sharedstatedir"), //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_sharedstatedir_tooltip);
controls.add(sharedstatedir);
IMesonPropertyPageControl buildtype = new MesonPropertyCombo(group, "buildtype", //$NON-NLS-1$
new String[] {"plain", "debug", "debugoptimized", "release", "minsize"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
argMap.get("--buildtype") != null ? argMap.get("--buildtype") : defaultBuildType, //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_buildtype_tooltip);
controls.add(buildtype);
IMesonPropertyPageControl strip = new MesonPropertySpecialCheckbox(group, "strip", argMap.get("--strip") != null, //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_strip_tooltip);
controls.add(strip);
IMesonPropertyPageControl unity = new MesonPropertyCombo(group, "unity", //$NON-NLS-1$
new String[] {"on", "off", "subprojects"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
argMap.get("--unity") != null ? argMap.get("--unity") : "off", //$NON-NLS-1$ //$NON-NLS-2$
Messages.MesonPropertyPage_unity_tooltip);
controls.add(unity);
IMesonPropertyPageControl werror = new MesonPropertySpecialCheckbox(group, "werror", //$NON-NLS-1$
argMap.get("--werror") != null, Messages.MesonPropertyPage_werror_tooltip); //$NON-NLS-1$
controls.add(werror);
IMesonPropertyPageControl layout = new MesonPropertyCombo(group, "layout", //$NON-NLS-1$
new String[] {"mirror", "flat"}, //$NON-NLS-1$ //$NON-NLS-2$
argMap.get("--mirror") != null ? argMap.get("--mirror") : "mirror", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Messages.MesonPropertyPage_layout_tooltip);
controls.add(layout);
IMesonPropertyPageControl default_library = new MesonPropertyCombo(group, "default-library", //$NON-NLS-1$
new String[] {"shared", "static"}, //$NON-NLS-1$ //$NON-NLS-2$
argMap.get("--default-library") != null ? argMap.get("--default-library") : "shared", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Messages.MesonPropertyPage_default_library_tooltip);
controls.add(default_library);
IMesonPropertyPageControl warnlevel = new MesonPropertyCombo(group, "warnlevel", //$NON-NLS-1$
new String[] {"1","2","3"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
argMap.get("--warnlevel") != null ? argMap.get("--warnlevel") : "1", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Messages.MesonPropertyPage_warnlevel_tooltip);
controls.add(warnlevel);
IMesonPropertyPageControl stdsplit = new MesonPropertySpecialCheckbox(group, "stdsplit", //$NON-NLS-1$
argMap.get("--stdsplit") != null, Messages.MesonPropertyPage_stdsplit_tooltip); //$NON-NLS-1$
controls.add(stdsplit);
IMesonPropertyPageControl errorlogs = new MesonPropertySpecialCheckbox(group, "errorlogs", //$NON-NLS-1$
argMap.get("--errorlogs") != null, Messages.MesonPropertyPage_errorlogs_tooltip); //$NON-NLS-1$
controls.add(errorlogs);
IMesonPropertyPageControl cross_file = new MesonPropertyText(group, "cross-file", //$NON-NLS-1$
argMap.get("--cross-file"), Messages.MesonPropertyPage_cross_file_tooltip); //$NON-NLS-1$
controls.add(cross_file);
IMesonPropertyPageControl wrap_mode = new MesonPropertyCombo(group, "wrap-mode", //$NON-NLS-1$
new String[] {"default", "nofallback", "nodownload"}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
argMap.get("--wrap-mode") != null ? argMap.get("--wrap-mode") : "default", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Messages.MesonPropertyPage_wrap_mode_tooltip);
controls.add(wrap_mode);
return controls;
}
}

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.swt.widgets.Composite;
public class MesonPropertySpecialCheckbox extends MesonPropertyCheckbox {
public MesonPropertySpecialCheckbox(Composite composite, String name, boolean initialValue, String tooltip) {
super(composite, name, initialValue, tooltip);
}
@Override
public String getUnconfiguredString() {
if (checkbox.getSelection()) {
return "--" + getFieldName(); //$NON-NLS-1$
}
return "";
}
}

View file

@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class MesonPropertyText implements IMesonPropertyPageControl {
private String name;
private String initialValue;
protected Text text;
public MesonPropertyText(Composite composite, String name, String initialValue, String tooltip) {
this.name = name;
if (initialValue == null) {
initialValue = ""; //$NON-NLS-1$
}
this.initialValue = initialValue;
Label label = new Label(composite, SWT.NONE);
label.setText(name);
label.setLayoutData(new GridData());
text = new Text(composite, SWT.SINGLE | SWT.BORDER);
GridData data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
text.setLayoutData(data);
text.setText(initialValue);
text.setToolTipText(tooltip);
}
@Override
public String getFieldValue() {
return text.getText();
}
@Override
public String getFieldName() {
return name;
}
@Override
public boolean isValueChanged() {
return !text.getText().equals(initialValue);
}
@Override
public boolean isValid() {
return true;
}
@Override
public String getUnconfiguredString() {
String value = getFieldValue();
if (value != null && !value.isEmpty()) {
return "--" + getFieldName() + "=" + getFieldValue(); //$NON-NLS-1$ //$NON-NLS-2$
}
return "";
}
@Override
public String getErrorMessage() {
return null;
}
}

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. 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:
* Red Hat Inc. - initial implementation
*******************************************************************************/
package org.eclipse.cdt.meson.ui.properties;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
public static String MesonPropertyPage_not_an_integer;
public static String MesonPropertyPage_option_pattern;
public static String MesonPropertyPage_option_with_values_pattern;
public static String MesonPropertyPage_compiler_or_link_args;
public static String MesonPropertyPage_arg_description;
public static String MesonPropertyPage_meson_error;
public static String MesonPropertyPage_configure_failed;
public static String MesonPropertyPage_terminated_rc;
public static String MesonPropertyPage_prefix_tooltip;
public static String MesonPropertyPage_libdir_tooltip;
public static String MesonPropertyPage_libexecdir_tooltip;
public static String MesonPropertyPage_bindir_tooltip;
public static String MesonPropertyPage_sbindir_tooltip;
public static String MesonPropertyPage_includedir_tooltip;
public static String MesonPropertyPage_datadir_tooltip;
public static String MesonPropertyPage_mandir_tooltip;
public static String MesonPropertyPage_infodir_tooltip;
public static String MesonPropertyPage_localedir_tooltip;
public static String MesonPropertyPage_sysconfdir_tooltip;
public static String MesonPropertyPage_localstatedir_tooltip;
public static String MesonPropertyPage_sharedstatedir_tooltip;
public static String MesonPropertyPage_buildtype_tooltip;
public static String MesonPropertyPage_strip_tooltip;
public static String MesonPropertyPage_unity_tooltip;
public static String MesonPropertyPage_werror_tooltip;
public static String MesonPropertyPage_layout_tooltip;
public static String MesonPropertyPage_default_library_tooltip;
public static String MesonPropertyPage_warnlevel_tooltip;
public static String MesonPropertyPage_stdsplit_tooltip;
public static String MesonPropertyPage_errorlogs_tooltip;
public static String MesonPropertyPage_cross_file_tooltip;
public static String MesonPropertyPage_wrap_mode_tooltip;
public static String MesonPropertyPage_true;
public static String MesonPropertyPage_false;
static {
// initialize resource bundle
NLS.initializeMessages("org.eclipse.cdt.meson.ui.properties.messages", Messages.class); //$NON-NLS-1$
}
private Messages() {
}
}

View file

@ -0,0 +1,46 @@
################################################################################
# Copyright (c) 2018 Red Hat Inc. 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:
# Red Hat Inc. - initial implementation
################################################################################
MesonPropertyPage_not_an_integer=Error: field {0} must be an integer
MesonPropertyPage_option_pattern=Option\\s+Current.Value\\s+Description.*$
MesonPropertyPage_option_with_values_pattern = Option\\s+Current.Value\\s+Possible.Values\\s+Description.*$
MesonPropertyPage_compiler_or_link_args=((Compiler arguments:)|(Linker args:))
MesonPropertyPage_arg_description=Compiler / linker arguments
MesonPropertyPage_meson_error=Meson configurator encountered an error:
MesonPropertyPage_configure_failed=Meson configure command failed (see console output)
MesonPropertyPage_terminated_rc=Command terminated with rc={0}\n
MesonPropertyPage_prefix_tooltip=Installation prefix
MesonPropertyPage_libdir_tooltip=Library directory
MesonPropertyPage_libexecdir_tooltip=Library executable directory
MesonPropertyPage_bindir_tooltip=Executable directory
MesonPropertyPage_sbindir_tooltip=System executable directory
MesonPropertyPage_includedir_tooltip=Header file directory
MesonPropertyPage_datadir_tooltip=Data file directory
MesonPropertyPage_mandir_tooltip=Manual page directory
MesonPropertyPage_infodir_tooltip=Info page directory
MesonPropertyPage_localedir_tooltip=Locale data directory
MesonPropertyPage_sysconfdir_tooltip=Sysconf data directory
MesonPropertyPage_localstatedir_tooltip=Localstate data directory
MesonPropertyPage_sharedstatedir_tooltip=Architecture-independent data directory
MesonPropertyPage_buildtype_tooltip=Build type to use
MesonPropertyPage_strip_tooltip=Strip targets on install
MesonPropertyPage_unity_tooltip=Unity build
MesonPropertyPage_werror_tooltip=Treat warnings as errors
MesonPropertyPage_layout_tooltip=Build directory layout
MesonPropertyPage_default_library_tooltip=Default library type
MesonPropertyPage_warnlevel_tooltip=Compiler warning level to use
MesonPropertyPage_stdsplit_tooltip=Split stdout and stderr in test logs
MesonPropertyPage_errorlogs_tooltip=Whether to print the logs from failing tests
MesonPropertyPage_cross_file_tooltip=File describing cross compilation environment
MesonPropertyPage_wrap_mode_tooltip=Special wrap mode to use
MesonPropertyPage_true=true
MesonPropertyPage_false=false

View file

@ -74,6 +74,10 @@
<module>build/org.eclipse.cdt.cmake.ui</module>
<module>build/org.eclipse.cdt.cmake-feature</module>
<module>build/org.eclipse.cdt.meson.core</module>
<module>build/org.eclipse.cdt.meson.ui</module>
<module>build/org.eclipse.cdt.meson-feature</module>
<module>build/org.eclipse.cdt.core.autotools.core</module>
<module>build/org.eclipse.cdt.core.autotools.ui</module>
<module>build/org.eclipse.cdt.core.autotools-feature</module>