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
This commit is contained in:
parent
bcff13debc
commit
ad430c0daa
1 changed files with 16 additions and 10 deletions
|
|
@ -493,7 +493,10 @@ proc needsExeExt(conf: ConfigRef): bool {.inline.} =
|
||||||
(conf.target.hostOS == osWindows)
|
(conf.target.hostOS == osWindows)
|
||||||
|
|
||||||
proc useCpp(conf: ConfigRef; cfile: AbsoluteFile): bool =
|
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 =
|
proc envFlags(conf: ConfigRef): string =
|
||||||
result = if conf.backend == backendCpp:
|
result = if conf.backend == backendCpp:
|
||||||
|
|
@ -501,14 +504,14 @@ proc envFlags(conf: ConfigRef): string =
|
||||||
else:
|
else:
|
||||||
getEnv("CFLAGS")
|
getEnv("CFLAGS")
|
||||||
|
|
||||||
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; cfile: AbsoluteFile): string =
|
proc getCompilerExe(conf: ConfigRef; compiler: TSystemCC; isCpp: bool): string =
|
||||||
if compiler == ccEnv:
|
if compiler == ccEnv:
|
||||||
result = if useCpp(conf, cfile):
|
result = if isCpp:
|
||||||
getEnv("CXX")
|
getEnv("CXX")
|
||||||
else:
|
else:
|
||||||
getEnv("CC")
|
getEnv("CC")
|
||||||
else:
|
else:
|
||||||
result = if useCpp(conf, cfile):
|
result = if isCpp:
|
||||||
CC[compiler].cppCompiler
|
CC[compiler].cppCompiler
|
||||||
else:
|
else:
|
||||||
CC[compiler].compilerExe
|
CC[compiler].compilerExe
|
||||||
|
|
@ -547,22 +550,25 @@ proc ccHasSaneOverflow*(conf: ConfigRef): bool =
|
||||||
|
|
||||||
proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
|
proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
|
||||||
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
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, optMixedMode in conf.globalOptions or conf.backend == backendCpp)
|
||||||
else: getCompilerExe(conf, compiler, AbsoluteFile"")
|
|
||||||
|
|
||||||
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
|
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
|
||||||
isMainFile = false; produceOutput = false): string =
|
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
|
# We produce files like module.nim.cpp, so the absolute Nim filename is not
|
||||||
# cfile.name but `cfile.cname.changeFileExt("")`:
|
# cfile.name but `cfile.cname.changeFileExt("")`:
|
||||||
var options = cFileSpecificOptions(conf, cfile.nimname, cfile.cname.changeFileExt("").string)
|
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.
|
# needs to be prepended so that --passc:-std=c++17 can override default.
|
||||||
# we could avoid allocation by making cFileSpecificOptions inplace
|
# we could avoid allocation by making cFileSpecificOptions inplace
|
||||||
options = CC[c].cppXsupport & ' ' & options
|
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")
|
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 needsExeExt(conf): exe = addFileExt(exe, "exe")
|
||||||
if (optGenDynLib in conf.globalOptions or (conf.hcrOn and not isMainFile)) and
|
if (optGenDynLib in conf.globalOptions or (conf.hcrOn and not isMainFile)) and
|
||||||
|
|
@ -582,7 +588,7 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
|
||||||
|
|
||||||
compilePattern = joinPath(conf.cCompilerPath, exe)
|
compilePattern = joinPath(conf.cCompilerPath, exe)
|
||||||
else:
|
else:
|
||||||
compilePattern = getCompilerExe(conf, c, cfile.cname)
|
compilePattern = getCompilerExe(conf, c, isCpp)
|
||||||
|
|
||||||
includeCmd.add(join([CC[c].includeCmd, quoteShell(conf.projectPath.string)]))
|
includeCmd.add(join([CC[c].includeCmd, quoteShell(conf.projectPath.string)]))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue