once C++, always C++ [backport] (#19938)

* once C++, always C++

When using `{.compile: "file.cc".}` in a nim module, even when compiling
with `nim c` the C++ compiler should be used - once any C++ file has
been compiled, the C++ linker also needs to be used.

* more strict C++ check

* simplify code

(cherry picked from commit ad430c0daa)
This commit is contained in:
Jacek Sieka
2022-06-30 10:20:19 +02:00
committed by narimiran
parent c9a52971f4
commit 7c7815402a

View File

@@ -483,7 +483,10 @@ proc needsExeExt(conf: ConfigRef): bool {.inline.} =
(conf.target.hostOS == osWindows)
proc useCpp(conf: ConfigRef; cfile: AbsoluteFile): bool =
conf.backend == backendCpp and not cfile.string.endsWith(".c")
# List of possible file extensions taken from gcc
for ext in [".C", ".cc", ".cpp", ".CPP", ".c++", ".cp", ".cxx"]:
if cfile.string.endsWith(ext): return true
false
proc envFlags(conf: ConfigRef): string =
result = if conf.backend == backendCpp:
@@ -491,14 +494,14 @@ proc envFlags(conf: ConfigRef): string =
else:
getEnv("CFLAGS")
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: AbsoluteFile): string =
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; isCpp: bool): string =
if compiler == ccEnv:
result = if useCpp(conf, cfile):
result = if isCpp:
getEnv("CXX")
else:
getEnv("CC")
else:
result = if useCpp(conf, cfile):
result = if isCpp:
CC[compiler].cppCompiler
else:
CC[compiler].compilerExe
@@ -537,22 +540,25 @@ proc ccHasSaneOverflow*(conf: ConfigRef): bool =
proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
elif optMixedMode in conf.globalOptions and conf.backend != backendCpp: CC[compiler].cppCompiler
else: getCompilerExe(conf, compiler, AbsoluteFile"")
else: getCompilerExe(conf, compiler, optMixedMode in conf.globalOptions or conf.backend == backendCpp)
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
isMainFile = false; produceOutput = false): string =
let c = conf.cCompiler
let
c = conf.cCompiler
isCpp = useCpp(conf, cfile.cname)
# We produce files like module.nim.cpp, so the absolute Nim filename is not
# cfile.name but `cfile.cname.changeFileExt("")`:
var options = cFileSpecificOptions(conf, cfile.nimname, cfile.cname.changeFileExt("").string)
if useCpp(conf, cfile.cname):
if isCpp:
# needs to be prepended so that --passc:-std=c++17 can override default.
# we could avoid allocation by making cFileSpecificOptions inplace
options = CC[c].cppXsupport & ' ' & options
# If any C++ file was compiled, we need to use C++ driver for linking as well
incl conf.globalOptions, optMixedMode
var exe = getConfigVar(conf, c, ".exe")
if exe.len == 0: exe = getCompilerExe(conf, c, cfile.cname)
if exe.len == 0: exe = getCompilerExe(conf, c, isCpp)
if needsExeExt(conf): exe = addFileExt(exe, "exe")
if (optGenDynLib in conf.globalOptions or (conf.hcrOn and not isMainFile)) and
@@ -572,7 +578,7 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
compilePattern = joinPath(conf.cCompilerPath, exe)
else:
compilePattern = getCompilerExe(conf, c, cfile.cname)
compilePattern = getCompilerExe(conf, c, isCpp)
includeCmd.add(join([CC[c].includeCmd, quoteShell(conf.projectPath.string)]))