Skip to content

Commit 44fc987

Browse files
dzhidzhoevlabath
andauthored
[lldb][test] Toolchain detection rewrite in Python (#102185)
This fix is based on a problem with cxx_compiler and cxx_linker macros on Windows. There was an issue with compiler detection in paths containing "icc". In such case, Makefile.rules thought it was provided with icc compiler. To solve that, utilities detection has been rewritten in Python. The last element of compiler's path is separated, taking into account the platform path delimiter, and compiler type is extracted, with regard of possible cross-toolchain prefix. --------- Co-authored-by: Pavel Labath <[email protected]>
1 parent 2a130f1 commit 44fc987

File tree

23 files changed

+139
-106
lines changed

23 files changed

+139
-106
lines changed

lldb/packages/Python/lldbsuite/test/builders/builder.py

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import os
2+
import pathlib
23
import platform
34
import subprocess
45
import sys
56
import itertools
67

78
import lldbsuite.test.lldbtest as lldbtest
9+
import lldbsuite.test.lldbplatformutil as lldbplatformutil
810
import lldbsuite.test.lldbutil as lldbutil
911
from lldbsuite.test import configuration
1012
from lldbsuite.test_event import build_exception
@@ -96,17 +98,101 @@ def getArchSpec(self, architecture):
9698
"""
9799
return ["ARCH=" + architecture] if architecture else []
98100

99-
def getCCSpec(self, compiler):
101+
def getToolchainSpec(self, compiler):
100102
"""
101-
Helper function to return the key-value string to specify the compiler
103+
Helper function to return the key-value strings to specify the toolchain
102104
used for the make system.
103105
"""
104106
cc = compiler if compiler else None
105107
if not cc and configuration.compiler:
106108
cc = configuration.compiler
107-
if cc:
108-
return ['CC="%s"' % cc]
109-
return []
109+
110+
if not cc:
111+
return []
112+
113+
cc = cc.strip()
114+
cc_path = pathlib.Path(cc)
115+
116+
# We can get CC compiler string in the following formats:
117+
# [<tool>] <compiler> - such as 'xrun clang', 'xrun /usr/bin/clang' & etc
118+
#
119+
# Where <compiler> could contain the following parts:
120+
# <simple-name>[.<exe-ext>] - sucn as 'clang', 'clang.exe' ('clang-cl.exe'?)
121+
# <target-triple>-<simple-name>[.<exe-ext>] - such as 'armv7-linux-gnueabi-gcc'
122+
# <path>/<simple-name>[.<exe-ext>] - such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
123+
# <path>/<target-triple>-<simple-name>[.<exe-ext>] - such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
124+
125+
cc_ext = cc_path.suffix
126+
# Compiler name without extension
127+
cc_name = cc_path.stem.split(" ")[-1]
128+
129+
# A kind of compiler (canonical name): clang, gcc, cc & etc.
130+
cc_type = cc_name
131+
# A triple prefix of compiler name: <armv7-none-linux-gnu->gcc
132+
cc_prefix = ""
133+
if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
134+
cc_name_parts = cc_name.split("-")
135+
cc_type = cc_name_parts[-1]
136+
if len(cc_name_parts) > 1:
137+
cc_prefix = "-".join(cc_name_parts[:-1]) + "-"
138+
139+
# A kind of C++ compiler.
140+
cxx_types = {
141+
"icc": "icpc",
142+
"llvm-gcc": "llvm-g++",
143+
"gcc": "g++",
144+
"cc": "c++",
145+
"clang": "clang++",
146+
}
147+
cxx_type = cxx_types.get(cc_type, cc_type)
148+
149+
cc_dir = cc_path.parent
150+
151+
def getToolchainUtil(util_name):
152+
return cc_dir / (cc_prefix + util_name + cc_ext)
153+
154+
cxx = getToolchainUtil(cxx_type)
155+
156+
util_names = {
157+
"OBJCOPY": "objcopy",
158+
"STRIP": "strip",
159+
"ARCHIVER": "ar",
160+
"DWP": "dwp",
161+
}
162+
utils = []
163+
164+
if not lldbplatformutil.platformIsDarwin():
165+
if cc_type in ["clang", "cc", "gcc"]:
166+
util_paths = {}
167+
# Assembly a toolchain side tool cmd based on passed CC.
168+
for var, name in util_names.items():
169+
# Do not override explicity specified tool from the cmd line.
170+
if not os.getenv(var):
171+
util_paths[var] = getToolchainUtil(name)
172+
else:
173+
util_paths[var] = os.getenv(var)
174+
utils.extend(["AR=%s" % util_paths["ARCHIVER"]])
175+
176+
# Look for llvm-dwp or gnu dwp
177+
if not lldbutil.which(util_paths["DWP"]):
178+
util_paths["DWP"] = getToolchainUtil("llvm-dwp")
179+
if not lldbutil.which(util_paths["DWP"]):
180+
util_paths["DWP"] = lldbutil.which("llvm-dwp")
181+
if not util_paths["DWP"]:
182+
util_paths["DWP"] = lldbutil.which("dwp")
183+
if not util_paths["DWP"]:
184+
del util_paths["DWP"]
185+
186+
for var, path in util_paths.items():
187+
utils.append("%s=%s" % (var, path))
188+
else:
189+
utils.extend(["AR=%slibtool" % os.getenv("CROSS_COMPILE", "")])
190+
191+
return [
192+
"CC=%s" % cc,
193+
"CC_TYPE=%s" % cc_type,
194+
"CXX=%s" % cxx,
195+
] + utils
110196

111197
def getSDKRootSpec(self):
112198
"""
@@ -178,7 +264,7 @@ def getBuildCommand(
178264
make_targets,
179265
self.getArchCFlags(architecture),
180266
self.getArchSpec(architecture),
181-
self.getCCSpec(compiler),
267+
self.getToolchainSpec(compiler),
182268
self.getExtraMakeArgs(),
183269
self.getSDKRootSpec(),
184270
self.getModuleCacheSpec(),

lldb/packages/Python/lldbsuite/test/make/Makefile.rules

Lines changed: 18 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,22 @@ endif
102102
# If you change the defaults of CC, be sure to also change it in the file
103103
# test/builders/builder_base.py, which provides a Python way to return the
104104
# value of the make variable CC -- getCompiler().
105-
#
106-
# See also these functions:
107-
# o cxx_compiler
108-
# o cxx_linker
109105
#----------------------------------------------------------------------
110106
ifeq "$(CC)" ""
111107
$(error "C compiler is not specified. Please run tests through lldb-dotest or lit")
112108
endif
113109

110+
# Always override the linker. Assign already normalized CC.
111+
override LD := $(CC)
112+
# A kind of linker. It always gets retrieved from CC.
113+
override LDC := $(CC_TYPE)
114+
115+
ifeq "$(HOST_OS)" "Windows_NT"
116+
# This function enframes the full path with the platform specific quotes. This is necessary to run the c++ executable
117+
# properly under 'sh' on Windows host (prevent the path breakage because of Windows style path separators).
118+
override CXX := $(QUOTE)$(CXX)$(QUOTE)
119+
endif
120+
114121
#----------------------------------------------------------------------
115122
# Handle SDKROOT for the cross platform builds.
116123
#----------------------------------------------------------------------
@@ -147,10 +154,8 @@ ifeq "$(OS)" "Darwin"
147154
DS := $(DSYMUTIL)
148155
DSFLAGS := $(DSFLAGS_EXTRAS)
149156
DSYM = $(EXE).dSYM
150-
AR := $(CROSS_COMPILE)libtool
151157
ARFLAGS := -static -o
152158
else
153-
AR := $(CROSS_COMPILE)ar
154159
# On non-Apple platforms, -arch becomes -m
155160
ARCHFLAG := -m
156161

@@ -213,7 +218,7 @@ endif
213218
LIMIT_DEBUG_INFO_FLAGS =
214219
NO_LIMIT_DEBUG_INFO_FLAGS =
215220
MODULE_DEBUG_INFO_FLAGS =
216-
ifneq (,$(findstring clang,$(CC)))
221+
ifeq ($(CC_TYPE), clang)
217222
LIMIT_DEBUG_INFO_FLAGS += -flimit-debug-info
218223
NO_LIMIT_DEBUG_INFO_FLAGS += -fno-limit-debug-info
219224
MODULE_DEBUG_INFO_FLAGS += -gmodules
@@ -279,7 +284,6 @@ endif
279284

280285
CFLAGS += $(CFLAGS_EXTRAS)
281286
CXXFLAGS += -std=c++11 $(CFLAGS) $(ARCH_CXXFLAGS)
282-
LD = $(CC)
283287
# Copy common options to the linker flags (dwarf, arch. & etc).
284288
# Note: we get some 'garbage' options for linker here (such as -I, --isystem & etc).
285289
LDFLAGS += $(CFLAGS)
@@ -312,61 +316,6 @@ ifneq "$(DYLIB_NAME)" ""
312316
endif
313317
endif
314318

315-
# Function that returns the counterpart C++ compiler, given $(CC) as arg.
316-
cxx_compiler_notdir = $(if $(findstring icc,$(1)), \
317-
$(subst icc,icpc,$(1)), \
318-
$(if $(findstring llvm-gcc,$(1)), \
319-
$(subst llvm-gcc,llvm-g++,$(1)), \
320-
$(if $(findstring gcc,$(1)), \
321-
$(subst gcc,g++,$(1)), \
322-
$(subst cc,c++,$(1)))))
323-
cxx_compiler = $(if $(findstring /,$(1)),$(join $(dir $(1)), $(call cxx_compiler_notdir,$(notdir $(1)))),$(call cxx_compiler_notdir,$(1)))
324-
325-
# Function that returns the C++ linker, given $(CC) as arg.
326-
cxx_linker_notdir = $(if $(findstring icc,$(1)), \
327-
$(subst icc,icpc,$(1)), \
328-
$(if $(findstring llvm-gcc,$(1)), \
329-
$(subst llvm-gcc,llvm-g++,$(1)), \
330-
$(if $(findstring gcc,$(1)), \
331-
$(subst gcc,g++,$(1)), \
332-
$(subst cc,c++,$(1)))))
333-
cxx_linker = $(if $(findstring /,$(1)),$(join $(dir $(1)), $(call cxx_linker_notdir,$(notdir $(1)))),$(call cxx_linker_notdir,$(1)))
334-
335-
ifneq "$(OS)" "Darwin"
336-
CLANG_OR_GCC := $(strip $(if $(findstring clang,$(CC)), \
337-
$(findstring clang,$(CC)), \
338-
$(if $(findstring gcc,$(CC)), \
339-
$(findstring gcc,$(CC)), \
340-
cc)))
341-
342-
CC_LASTWORD := $(strip $(lastword $(subst -, ,$(CC))))
343-
344-
replace_with = $(strip $(if $(findstring $(3),$(CC_LASTWORD)), \
345-
$(subst $(3),$(1),$(2)), \
346-
$(subst $(3),$(1),$(subst -$(CC_LASTWORD),,$(2)))))
347-
348-
ifeq "$(notdir $(CC))" "$(CC)"
349-
replace_cc_with = $(call replace_with,$(1),$(CC),$(CLANG_OR_GCC))
350-
else
351-
replace_cc_with = $(join $(dir $(CC)),$(call replace_with,$(1),$(notdir $(CC)),$(CLANG_OR_GCC)))
352-
endif
353-
354-
OBJCOPY ?= $(call replace_cc_with,objcopy)
355-
ARCHIVER ?= $(call replace_cc_with,ar)
356-
# Look for llvm-dwp or gnu dwp
357-
DWP ?= $(call replace_cc_with,llvm-dwp)
358-
ifeq ($(wildcard $(DWP)),)
359-
DWP = $(call replace_cc_with,dwp)
360-
ifeq ($(wildcard $(DWP)),)
361-
DWP = $(shell command -v llvm-dwp 2> /dev/null)
362-
ifeq ($(wildcard $(DWP)),)
363-
DWP = $(shell command -v dwp 2> /dev/null)
364-
endif
365-
endif
366-
endif
367-
override AR = $(ARCHIVER)
368-
endif
369-
370319
ifdef PIE
371320
LDFLAGS += -pie
372321
endif
@@ -375,7 +324,7 @@ endif
375324
# Windows specific options
376325
#----------------------------------------------------------------------
377326
ifeq "$(OS)" "Windows_NT"
378-
ifneq (,$(findstring clang,$(CC)))
327+
ifeq ($(CC_TYPE), clang)
379328
# Clang for Windows doesn't support C++ Exceptions
380329
CXXFLAGS += -fno-exceptions
381330
CXXFLAGS += -D_HAS_EXCEPTIONS=0
@@ -420,7 +369,7 @@ endif
420369

421370
ifeq (1,$(USE_LIBSTDCPP))
422371
# Clang requires an extra flag: -stdlib=libstdc++
423-
ifneq (,$(findstring clang,$(CC)))
372+
ifeq ($(CC_TYPE), clang)
424373
# Force clang looking for the gcc's headers at specific rootfs folder.
425374
CXXFLAGS += -stdlib=libstdc++ $(GCC_TOOLCHAIN_FLAGS)
426375
LDFLAGS += -stdlib=libstdc++ $(GCC_TOOLCHAIN_FLAGS)
@@ -458,7 +407,7 @@ ifeq (1, $(USE_SYSTEM_STDLIB))
458407
CXXFLAGS += -nostdlib++ -nostdinc++ -cxx-isystem $(SDKROOT)/usr/include/c++/v1
459408
LDFLAGS += -L$(SDKROOT)/usr/lib -Wl,-rpath,$(SDKROOT)/usr/lib -lc++
460409
else
461-
ifneq (,$(findstring clang,$(CC)))
410+
ifeq ($(CC_TYPE),clang)
462411
# Force clang looking for the gcc's headers at specific rootfs folder.
463412
CXXFLAGS += $(GCC_TOOLCHAIN_FLAGS)
464413
LDFLAGS += $(GCC_TOOLCHAIN_FLAGS)
@@ -485,8 +434,6 @@ DYLIB_OBJECTS +=$(strip $(DYLIB_C_SOURCES:.c=.o))
485434
DYLIB_OBJECTS +=$(strip $(DYLIB_OBJC_SOURCES:.m=.o))
486435
ifneq "$(strip $(DYLIB_CXX_SOURCES))" ""
487436
DYLIB_OBJECTS +=$(strip $(patsubst %.mm, %.o, $(DYLIB_CXX_SOURCES:.cpp=.o)))
488-
CXX = $(call cxx_compiler,$(CC))
489-
LD = $(call cxx_linker,$(CC))
490437
endif
491438

492439
#----------------------------------------------------------------------
@@ -509,8 +456,6 @@ endif
509456
#----------------------------------------------------------------------
510457
ifneq "$(strip $(CXX_SOURCES))" ""
511458
OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o))
512-
CXX = $(call cxx_compiler,$(CC))
513-
LD = $(call cxx_linker,$(CC))
514459
endif
515460

516461
#----------------------------------------------------------------------
@@ -526,19 +471,18 @@ endif
526471
#----------------------------------------------------------------------
527472
ifneq "$(strip $(OBJCXX_SOURCES))" ""
528473
OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o))
529-
CXX = $(call cxx_compiler,$(CC))
530-
LD = $(call cxx_linker,$(CC))
531474
ifeq "$(findstring lobjc,$(LDFLAGS))" ""
532475
LDFLAGS +=-lobjc
533476
endif
534477
endif
535478

536-
ifeq ($(findstring clang, $(CXX)), clang)
479+
ifeq ($(CC_TYPE), clang)
537480
CXXFLAGS += --driver-mode=g++
538481
endif
539482

540483
ifneq "$(CXX)" ""
541-
ifeq ($(findstring clang, $(LD)), clang)
484+
# Specify the driver mode parameter if we use clang as the linker.
485+
ifeq ($(LDC), clang)
542486
LDFLAGS += --driver-mode=g++
543487
endif
544488
endif

lldb/test/API/functionalities/breakpoint/breakpoint_ids/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CXX_SOURCES := main.cpp
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CXXFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/breakpoint_locations/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
C_SOURCES := main.c
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/consecutive_breakpoints/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CXX_SOURCES := main.cpp
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CXXFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/cpp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CXX_SOURCES := main.cpp
22
CXXFLAGS_EXTRAS := -std=c++14
33

4-
ifneq (,$(findstring icc,$(CC)))
4+
ifeq ($(CC_TYPE), icc)
55
CXXFLAGS_EXTRAS := -debug inline-debug-info
66
endif
77

lldb/test/API/functionalities/breakpoint/dummy_target_breakpoints/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
C_SOURCES := main.c
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/hardware_breakpoints/require_hw_breakpoints/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
C_SOURCES := main.c
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/step_over_breakpoint/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CXX_SOURCES := main.cpp
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CXXFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CXX_SOURCES := main.cpp
22

3-
ifneq (,$(findstring icc,$(CC)))
3+
ifeq ($(CC_TYPE), icc)
44
CXXFLAGS_EXTRAS := -debug inline-debug-info
55
endif
66

lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ def appkit_tester_impl(self, commands, use_constant_classes):
1616
self.build()
1717
else:
1818
disable_constant_classes = {
19-
"CC": "xcrun clang", # FIXME: Remove when flags are available upstream.
2019
"CFLAGS_EXTRAS": "-fno-constant-nsnumber-literals "
2120
+ "-fno-constant-nsarray-literals "
2221
+ "-fno-constant-nsdictionary-literals",
2322
}
24-
self.build(dictionary=disable_constant_classes)
23+
# FIXME: Remove compiler when flags are available upstream.
24+
self.build(dictionary=disable_constant_classes, compiler="xcrun clang")
2525
self.appkit_common_data_formatters_command()
2626
commands()
2727

0 commit comments

Comments
 (0)