mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
Merge 680f66243b
into b4d81a130e
This commit is contained in:
commit
5ae490a1ee
2 changed files with 198 additions and 2 deletions
|
@ -0,0 +1,116 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2025 Renesas Electronics Europe.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.build.gcc.core.tests;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.cdt.build.gcc.core.ClangToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.envvar.EnvironmentVariable;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for org.eclipse.cdt.build.gcc.core.ClangToolChain
|
||||
* Tests that the environment variables CC and CXX are set to clang values.
|
||||
*/
|
||||
public class TestClangToolChain {
|
||||
|
||||
/**
|
||||
* Tests ClangToolChain.ClangToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
|
||||
IEnvironmentVariable[] envVars).
|
||||
* Where envVars is null.
|
||||
* Expected:
|
||||
* envVars contains "CC=clang", "CXX=clang++"
|
||||
*/
|
||||
@Test
|
||||
public void clangContainsEnvVarsNull() throws Exception {
|
||||
IToolChain tc = new ClangToolChain(null, null, null, null);
|
||||
IEnvironmentVariable[] variables = tc.getVariables();
|
||||
assertThat(Arrays.asList(variables), contains(//
|
||||
new EnvironmentVariable("CC", "clang"), //
|
||||
new EnvironmentVariable("CXX", "clang++")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests ClangToolChain.ClangToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
|
||||
IEnvironmentVariable[] envVars).
|
||||
* Where envVars is empty.
|
||||
* Expected:
|
||||
* envVars contains "CC=clang", "CXX=clang++"
|
||||
*/
|
||||
@Test
|
||||
public void clangContainsEnvVarsEmpty() throws Exception {
|
||||
IEnvironmentVariable[] envVars = {};
|
||||
IToolChain tc = new ClangToolChain(null, null, null, envVars);
|
||||
IEnvironmentVariable[] variables = tc.getVariables();
|
||||
assertThat(Arrays.asList(variables), contains(//
|
||||
new EnvironmentVariable("CC", "clang"), //
|
||||
new EnvironmentVariable("CXX", "clang++")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests ClangToolChain.ClangToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
|
||||
IEnvironmentVariable[] envVars).
|
||||
* Where envVars contains "cc=testvalue"
|
||||
* Expected:
|
||||
* (Windows): envVars contains "CC=testvalue", "CXX=clang++"
|
||||
* (non-Windows): envVars contains "cc=testvalue", "CC=clang", "CXX=clang++"
|
||||
*/
|
||||
@Test
|
||||
public void clangContainscc() throws Exception {
|
||||
IEnvironmentVariable[] envVars = { new EnvironmentVariable("cc", "testvalue") };
|
||||
IToolChain tc = new ClangToolChain(null, null, null, envVars);
|
||||
IEnvironmentVariable[] variables = tc.getVariables();
|
||||
|
||||
if (Platform.OS_WIN32.equals(Platform.getOS())) {
|
||||
/*
|
||||
* Windows: case-insensitive environment; cc is replaced with uppercase CC. value remains unchanged.
|
||||
*/
|
||||
assertThat(Arrays.asList(variables), not(hasItem(new EnvironmentVariable("cc", "testvalue"))));
|
||||
assertThat(Arrays.asList(variables),
|
||||
contains(new EnvironmentVariable("CC", "testvalue"), new EnvironmentVariable("CXX", "clang++")));
|
||||
// the clang override value not applied because the envVar already existed.
|
||||
assertThat(Arrays.asList(variables), not(hasItem(new EnvironmentVariable("CC", "clang"))));
|
||||
} else {
|
||||
/*
|
||||
* Non-Windows: case-sensitive environment; cc is not replaced with uppercase CC. CC is added in addition to any cc.
|
||||
*/
|
||||
assertThat(Arrays.asList(variables), contains(//
|
||||
new EnvironmentVariable("cc", "testvalue"), //
|
||||
new EnvironmentVariable("CC", "clang"), //
|
||||
new EnvironmentVariable("CXX", "clang++")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests ClangToolChain.ClangToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
|
||||
IEnvironmentVariable[] envVars).
|
||||
* Where envVars contains "CC=testvalue"
|
||||
* Expected:
|
||||
* envVars contains "CC=testvalue", "CXX=clang++"
|
||||
*/
|
||||
@Test
|
||||
public void clangContainsCC() throws Exception {
|
||||
IEnvironmentVariable[] envVars = { new EnvironmentVariable("CC", "testvalue") };
|
||||
IToolChain tc = new ClangToolChain(null, null, null, envVars);
|
||||
IEnvironmentVariable[] variables = tc.getVariables();
|
||||
assertThat(Arrays.asList(variables), contains(//
|
||||
new EnvironmentVariable("CC", "testvalue"), //
|
||||
new EnvironmentVariable("CXX", "clang++")));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 QNX Software Systems and others.
|
||||
* Copyright (c) 2017, 2025 QNX Software Systems and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -11,9 +11,15 @@
|
|||
package org.eclipse.cdt.build.gcc.core;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.envvar.EnvironmentVariable;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* The Clang toolchain. There's little different from the GCC toolchain other
|
||||
|
@ -28,7 +34,81 @@ public class ClangToolChain extends GCCToolChain {
|
|||
|
||||
public ClangToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
|
||||
IEnvironmentVariable[] envVars) {
|
||||
super(provider, pathToToolChain, arch, envVars);
|
||||
super(provider, pathToToolChain, arch, addClangEnvVars(envVars));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the environment variables CC and CXX, set to clang and clang++, to override the C/C++ compiler executable
|
||||
* that CMake uses.
|
||||
*
|
||||
* Other methods of setting the compiler in CMake (eg; CMAKE_<LANG>_COMPILER in CMakeLists.txt,
|
||||
* -DCMAKE_TOOLCHAIN_FILE=file) take precedence over these environment variables, so the user is not
|
||||
* inhibited by this approach.
|
||||
*
|
||||
* @param envVars Environment variables originate from the core build toolchain (either "Discovered toolchain" or
|
||||
* "User defined toolchain"); these are not the OS system envVars. When the tc is a user defined, it is possible to
|
||||
* specify arbitrary environment variables, meaning the user may have already defined CC/CXX.
|
||||
* If CC/CXX is already defined then nothing is added.
|
||||
*
|
||||
* @return the existing array of envVars, plus if they didn't already exist the envVars CC and CXX set for clang.
|
||||
*/
|
||||
private static IEnvironmentVariable[] addClangEnvVars(IEnvironmentVariable[] envVars) {
|
||||
List<IEnvironmentVariable> envVarsNew = new ArrayList<>();
|
||||
// envVars can be null if the user defined tc did not specify any env variables.
|
||||
if (envVars != null) {
|
||||
envVarsNew.addAll(Arrays.asList(envVars));
|
||||
}
|
||||
addIfAbsent("CC", "clang", envVarsNew); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
addIfAbsent("CXX", "clang++", envVarsNew); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
return envVarsNew.toArray(new EnvironmentVariable[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name The name of the environment variable.
|
||||
* On case insensitive platforms (windows) the case is ignored. If an envVar with the name "cc" already exists,
|
||||
* a new envVar will NOT be added.<br>
|
||||
*
|
||||
* However, on Windows, existing cc/cxx envVars with lower-case names will have their names changed to upper case;
|
||||
* the value remains unchanged.<br>
|
||||
*
|
||||
* On case sensitive platforms (Non-windows) the case is respected. If an envVar with the name "cc" already exists,
|
||||
* a new envVar with name "CC" will be added using the value in {@code value}.
|
||||
* @param value The value of the environment variable.
|
||||
* @param envVars List of environment variables to check and potentially add to.
|
||||
*/
|
||||
private static void addIfAbsent(String name, String value, List<IEnvironmentVariable> envVars) {
|
||||
if (Platform.OS_WIN32.equals(Platform.getOS())) {
|
||||
// On Windows: case-insensitive check ignores case.
|
||||
Iterator<IEnvironmentVariable> iterator = envVars.iterator();
|
||||
boolean found = false;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
IEnvironmentVariable ev = iterator.next();
|
||||
if (ev.getName().equalsIgnoreCase(name)) {
|
||||
found = true;
|
||||
// Replace if existing name is in lower-case and new name is in upper-case
|
||||
if (!ev.getName().equals(name) && name.equals(name.toUpperCase())) {
|
||||
// Original value is respected.
|
||||
String evOldValue = ev.getValue();
|
||||
iterator.remove();
|
||||
envVars.add(new EnvironmentVariable(name, evOldValue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
envVars.add(new EnvironmentVariable(name, value));
|
||||
}
|
||||
|
||||
} else {
|
||||
// On non-Windows: case-sensitive check respects case (exact match).
|
||||
boolean isAbsent = envVars.stream().noneMatch(ev -> ev.getName().equals(name));
|
||||
if (isAbsent) {
|
||||
envVars.add(new EnvironmentVariable(name, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Reference in a new issue