From 48a1d8e17359a65977cd8b3a6d535ad26ceaf9ea Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Sep 2015 16:05:04 -0400 Subject: castxml: Allow --castxml-cc- to detect C language settings If the "" is "gnu-c" or "msvc-c" then run the given compiler command line on a C source file instead of C++. This allows C language settings of the given compiler to be detected. --- doc/manual/castxml.1.rst | 4 +- share/castxml/detect_vs.c | 139 +++++++++++++++++++++++++ share/castxml/empty.c | 0 src/Detect.cxx | 28 +++-- src/castxml.cxx | 4 +- test/CMakeLists.txt | 6 ++ test/cc-gnu.c | 9 +- test/cc-msvc.c | 11 +- test/expect/cmd.cc-gnu-c-bad-cmd.result.txt | 1 + test/expect/cmd.cc-gnu-c-bad-cmd.stderr.txt | 3 + test/expect/cmd.cc-gnu-c-src-c-E.stdout.txt | 2 + test/expect/cmd.cc-gnu-c-src-c-cmd.stderr.txt | 1 + test/expect/cmd.cc-msvc-c-bad-cmd.result.txt | 1 + test/expect/cmd.cc-msvc-c-bad-cmd.stderr.txt | 3 + test/expect/cmd.cc-msvc-c-src-c-E.stdout.txt | 2 + test/expect/cmd.cc-msvc-c-src-c-cmd.stderr.txt | 1 + 16 files changed, 200 insertions(+), 15 deletions(-) create mode 100644 share/castxml/detect_vs.c create mode 100644 share/castxml/empty.c create mode 100644 test/expect/cmd.cc-gnu-c-bad-cmd.result.txt create mode 100644 test/expect/cmd.cc-gnu-c-bad-cmd.stderr.txt create mode 100644 test/expect/cmd.cc-gnu-c-src-c-E.stdout.txt create mode 100644 test/expect/cmd.cc-gnu-c-src-c-cmd.stderr.txt create mode 100644 test/expect/cmd.cc-msvc-c-bad-cmd.result.txt create mode 100644 test/expect/cmd.cc-msvc-c-bad-cmd.stderr.txt create mode 100644 test/expect/cmd.cc-msvc-c-src-c-E.stdout.txt create mode 100644 test/expect/cmd.cc-msvc-c-src-c-cmd.stderr.txt diff --git a/doc/manual/castxml.1.rst b/doc/manual/castxml.1.rst index ad255cc..181de8a 100644 --- a/doc/manual/castxml.1.rst +++ b/doc/manual/castxml.1.rst @@ -37,8 +37,10 @@ Remaining options are given to the internal Clang compiler. a reference compiler with which the given command is compatible. It must be one of: - * ``gnu``: GNU Compiler Collection (gcc) + * ``gnu``: GNU Compiler Collection C++ (g++) + * ``gnu-c``: GNU Compiler Collection C (gcc) * ``msvc``: Microsoft Visual C++ (cl) + * ``msvc-c``: Microsoft Visual C (cl) ```` names a compiler (e.g. ``/usr/bin/gcc`` or ``cl``) and ``...`` specifies options that may affect its target diff --git a/share/castxml/detect_vs.c b/share/castxml/detect_vs.c new file mode 100644 index 0000000..eca94bc --- /dev/null +++ b/share/castxml/detect_vs.c @@ -0,0 +1,139 @@ +/* + Copyright Kitware, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* cl -c -FoNUL detect_vs.c */ +#define TO_STRING0(x) #x +#define TO_STRING(x) TO_STRING0(x) +#define TO_DEFINE(x) "#define " #x " " TO_STRING(x) + +#pragma message("") +#ifdef __AVX__ +# pragma message(TO_DEFINE(__AVX__)) +#endif +#ifdef __AVX2__ +# pragma message(TO_DEFINE(__AVX2__)) +#endif +#ifdef _ATL_VER +# pragma message(TO_DEFINE(_ATL_VER)) +#endif +#ifdef _CHAR_UNSIGNED +# pragma message(TO_DEFINE(_CHAR_UNSIGNED)) +#endif +#ifdef _CPPRTTI +# pragma message(TO_DEFINE(_CPPRTTI)) +#endif +#ifdef _CPPUNWIND +# pragma message(TO_DEFINE(_CPPUNWIND)) +#endif +#ifdef _DEBUG +# pragma message(TO_DEFINE(_DEBUG)) +#endif +#ifdef _DLL +# pragma message(TO_DEFINE(_DLL)) +#endif +#ifdef _INTEGRAL_MAX_BITS +# pragma message(TO_DEFINE(_INTEGRAL_MAX_BITS)) +#endif +#ifdef _MANAGED +# pragma message(TO_DEFINE(_MANAGED)) +#endif +#ifdef _MFC_VER +# pragma message(TO_DEFINE(_MFC_VER)) +#endif +#ifdef _MSC_BUILD +# pragma message(TO_DEFINE(_MSC_BUILD)) +#endif +#ifdef _MSC_EXTENSIONS +# pragma message(TO_DEFINE(_MSC_EXTENSIONS)) +#endif +#ifdef _MSC_FULL_VER +# pragma message(TO_DEFINE(_MSC_FULL_VER)) +#endif +#ifdef _MSC_VER +# pragma message(TO_DEFINE(_MSC_VER)) +#endif +#ifdef _MT +# pragma message(TO_DEFINE(_MT)) +#endif +#ifdef _M_ALPHA +# pragma message(TO_DEFINE(_M_ALPHA)) +#endif +#ifdef _M_AMD64 +# pragma message(TO_DEFINE(_M_AMD64)) +#endif +#ifdef _M_ARM +# pragma message(TO_DEFINE(_M_ARM)) +#endif +#ifdef _M_ARM_FP +# pragma message(TO_DEFINE(_M_ARM_FP)) +#endif +#ifdef _M_CEE +# pragma message(TO_DEFINE(_M_CEE)) +#endif +#ifdef _M_CEE_PURE +# pragma message(TO_DEFINE(_M_CEE_PURE)) +#endif +#ifdef _M_CEE_SAFE +# pragma message(TO_DEFINE(_M_CEE_SAFE)) +#endif +#ifdef _M_IA64 +# pragma message(TO_DEFINE(_M_IA64)) +#endif +#ifdef _M_IX86 +# pragma message(TO_DEFINE(_M_IX86)) +#endif +#ifdef _M_IX86_FP +# pragma message(TO_DEFINE(_M_IX86_FP)) +#endif +#ifdef _M_MPPC +# pragma message(TO_DEFINE(_M_MPPC)) +#endif +#ifdef _M_MRX000 +# pragma message(TO_DEFINE(_M_MRX000)) +#endif +#ifdef _M_PPC +# pragma message(TO_DEFINE(_M_PPC)) +#endif +#ifdef _M_X64 +# pragma message(TO_DEFINE(_M_X64)) +#endif +#ifdef _NATIVE_WCHAR_T_DEFINED +# pragma message(TO_DEFINE(_NATIVE_WCHAR_T_DEFINED)) +#endif +#ifdef _OPENMP +# pragma message(TO_DEFINE(_OPENMP)) +#endif +#ifdef _VC_NODEFAULTLIB +# pragma message(TO_DEFINE(_VC_NODEFAULTLIB)) +#endif +#ifdef _WCHAR_T_DEFINED +# pragma message(TO_DEFINE(_WCHAR_T_DEFINED)) +#endif +#ifdef _WIN32 +# pragma message(TO_DEFINE(_WIN32)) +#endif +#ifdef _WIN64 +# pragma message(TO_DEFINE(_WIN64)) +#endif +#ifdef _Wp64 +# pragma message(TO_DEFINE(_Wp64)) +#endif +#ifdef __CLR_VER +# pragma message(TO_DEFINE(__CLR_VER)) +#endif +#ifdef __MSVC_RUNTIME_CHECKS +# pragma message(TO_DEFINE(__MSVC_RUNTIME_CHECKS)) +#endif diff --git a/share/castxml/empty.c b/share/castxml/empty.c new file mode 100644 index 0000000..e69de29 diff --git a/src/Detect.cxx b/src/Detect.cxx index 378b907..77b2c94 100644 --- a/src/Detect.cxx +++ b/src/Detect.cxx @@ -119,12 +119,14 @@ static void setTriple(Options& opts) //---------------------------------------------------------------------------- static bool detectCC_GNU(const char* const* argBeg, const char* const* argEnd, - Options& opts) + Options& opts, + const char* id, + const char* ext) { std::string const fwExplicitSuffix = " (framework directory)"; std::string const fwImplicitSuffix = "/Frameworks"; std::vector cc_args(argBeg, argEnd); - std::string empty_cpp = getResourceDir() + "/empty.cpp"; + std::string empty_cpp = getResourceDir() + "/empty." + ext; int ret; std::string out; std::string err; @@ -171,17 +173,19 @@ static bool detectCC_GNU(const char* const* argBeg, setTriple(opts); return true; } else { - return failedCC("gnu", cc_args, out, err, msg); + return failedCC(id, cc_args, out, err, msg); } } //---------------------------------------------------------------------------- static bool detectCC_MSVC(const char* const* argBeg, const char* const* argEnd, - Options& opts) + Options& opts, + const char* id, + const char* ext) { std::vector cc_args(argBeg, argEnd); - std::string detect_vs_cpp = getResourceDir() + "/detect_vs.cpp"; + std::string detect_vs_cpp = getResourceDir() + "/detect_vs." + ext; int ret; std::string out; std::string err; @@ -210,7 +214,7 @@ static bool detectCC_MSVC(const char* const* argBeg, setTriple(opts); return true; } else { - return failedCC("msvc", cc_args, out, err, msg); + return failedCC(id, cc_args, out, err, msg); } } @@ -220,10 +224,14 @@ bool detectCC(const char* id, const char* const* argEnd, Options& opts) { - if(strcmp(id, "gnu") == 0) { - return detectCC_GNU(argBeg, argEnd, opts); - } else if(strcmp(id, "msvc") == 0) { - return detectCC_MSVC(argBeg, argEnd, opts); + if (strcmp(id, "gnu") == 0) { + return detectCC_GNU(argBeg, argEnd, opts, id, "cpp"); + } else if (strcmp(id, "gnu-c") == 0) { + return detectCC_GNU(argBeg, argEnd, opts, id, "c"); + } else if (strcmp(id, "msvc") == 0) { + return detectCC_MSVC(argBeg, argEnd, opts, id, "cpp"); + } else if (strcmp(id, "msvc-c") == 0) { + return detectCC_MSVC(argBeg, argEnd, opts, id, "c"); } else { std::cerr << "error: '--castxml-cc-" << id << "' not known!\n"; return false; diff --git a/src/castxml.cxx b/src/castxml.cxx index 5ca6b5b..f686552 100644 --- a/src/castxml.cxx +++ b/src/castxml.cxx @@ -101,8 +101,8 @@ int main(int argc_in, const char** argv_in) " --castxml-cc- \"(\" ... \")\"\n" " Configure the internal Clang preprocessor and target\n" " platform to match that of the given compiler command.\n" - " The must be \"gnu\" or \"msvc\". names a\n" - " compiler (e.g. \"gcc\") and ... specifies\n" + " The must be \"gnu\", \"msvc\", \"gnu-c\", or \"msvc-c\".\n" + " names a compiler (e.g. \"gcc\") and ... specifies\n" " options that may affect its target (e.g. \"-m32\").\n" "\n" " --castxml-gccxml\n" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 29fcecf..9744919 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -160,6 +160,9 @@ castxml_test_cmd(cc-gnu-tgt-i386 --castxml-cc-gnu "(" $ --cc castxml_test_cmd(cc-gnu-tgt-mingw --castxml-cc-gnu "(" $ --cc-define=_WIN32 --cc-define=__MINGW32__ ")" ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-win --castxml-cc-gnu "(" $ --cc-define=_WIN32 ")" ${empty_cxx} "-###") castxml_test_cmd(cc-gnu-tgt-x86_64 --castxml-cc-gnu "(" $ --cc-define=__x86_64__ ")" ${empty_cxx} "-###") +castxml_test_cmd(cc-gnu-c-bad-cmd --castxml-cc-gnu-c "(" cc-gnu-c-bad-cmd ")" ${empty_c}) +castxml_test_cmd(cc-gnu-c-src-c-E --castxml-cc-gnu-c $ ${empty_c} -E -dM) +castxml_test_cmd(cc-gnu-c-src-c-cmd --castxml-cc-gnu-c $ ${empty_c} "-###") # Test --castxml-cc-msvc detection. add_executable(cc-msvc cc-msvc.c) @@ -174,6 +177,9 @@ castxml_test_cmd(cc-msvc-tgt-explicit --castxml-cc-msvc "(" $ --cc-define=_M_IX86 ")" ${empty_cxx} "-###") castxml_test_cmd(cc-msvc-tgt-win --castxml-cc-msvc "(" $ --cc-define=_WIN32 ")" ${empty_cxx} "-###") castxml_test_cmd(cc-msvc-tgt-x86_64 --castxml-cc-msvc "(" $ --cc-define=_M_X64 ")" ${empty_cxx} "-###") +castxml_test_cmd(cc-msvc-c-bad-cmd --castxml-cc-msvc-c "(" cc-msvc-c-bad-cmd ")" ${empty_c}) +castxml_test_cmd(cc-msvc-c-src-c-E --castxml-cc-msvc-c $ ${empty_c} -E -dM) +castxml_test_cmd(cc-msvc-c-src-c-cmd --castxml-cc-msvc-c $ ${empty_c} "-###") unset(castxml_test_cmd_extra_arguments) castxml_test_gccxml(ArrayType) diff --git a/test/cc-gnu.c b/test/cc-gnu.c index bd49475..b3f7400 100644 --- a/test/cc-gnu.c +++ b/test/cc-gnu.c @@ -3,14 +3,21 @@ int main(int argc, const char* argv[]) { + int cpp = 0; int i; for (i = 1; i < argc; ++i) { if (strncmp(argv[i], "--cc-define=", 12) == 0) { fprintf(stdout, "#define %s 1\n", argv[i]+12); + } else if (strstr(argv[i], ".cpp")) { + cpp = 1; } } + if (cpp) { + fprintf(stdout, + "#define __cplusplus 199711L\n" + ); + } fprintf(stdout, - "#define __cplusplus 199711L\n" "#define __GNUC__ 1\n" "#define __has_include(x) x\n" "#define __has_include_next(x) x\n" diff --git a/test/cc-msvc.c b/test/cc-msvc.c index 3d2cd58..9838a5e 100644 --- a/test/cc-msvc.c +++ b/test/cc-msvc.c @@ -3,15 +3,24 @@ int main(int argc, const char* argv[]) { + int cpp = 0; int i; for (i = 1; i < argc; ++i) { if (strncmp(argv[i], "--cc-define=", 12) == 0) { fprintf(stdout, "\n#define %s 1", argv[i]+12); + } else if (strstr(argv[i], ".cpp")) { + cpp = 1; } } fprintf(stdout, "\n" - "#define __cplusplus 199711L\n" + ); + if (cpp) { + fprintf(stdout, + "#define __cplusplus 199711L\n" + ); + } + fprintf(stdout, "#define _MSC_VER 1600\n" "#define __has_include(x) x\n" "#define __has_include_next(x) x\n" diff --git a/test/expect/cmd.cc-gnu-c-bad-cmd.result.txt b/test/expect/cmd.cc-gnu-c-bad-cmd.result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/expect/cmd.cc-gnu-c-bad-cmd.result.txt @@ -0,0 +1 @@ +1 diff --git a/test/expect/cmd.cc-gnu-c-bad-cmd.stderr.txt b/test/expect/cmd.cc-gnu-c-bad-cmd.stderr.txt new file mode 100644 index 0000000..117a4c5 --- /dev/null +++ b/test/expect/cmd.cc-gnu-c-bad-cmd.stderr.txt @@ -0,0 +1,3 @@ +^error: '--castxml-cc-gnu-c' compiler command failed: + + 'cc-gnu-c-bad-cmd' '-E' '-dM' '-v' '.*/share/castxml/empty.c' diff --git a/test/expect/cmd.cc-gnu-c-src-c-E.stdout.txt b/test/expect/cmd.cc-gnu-c-src-c-E.stdout.txt new file mode 100644 index 0000000..0a0cc7e --- /dev/null +++ b/test/expect/cmd.cc-gnu-c-src-c-E.stdout.txt @@ -0,0 +1,2 @@ +^#define __GNUC_MINOR__ 1 +#define __GNUC__ 1$ diff --git a/test/expect/cmd.cc-gnu-c-src-c-cmd.stderr.txt b/test/expect/cmd.cc-gnu-c-src-c-cmd.stderr.txt new file mode 100644 index 0000000..175c3bd --- /dev/null +++ b/test/expect/cmd.cc-gnu-c-src-c-cmd.stderr.txt @@ -0,0 +1 @@ +"clang" .* "-[^i][^"]*" "[^-"][^"]*" "-isystem" "/some/include" "-isystem" "[^"]*/include" "-iframework" "/some/Frameworks" "-iframework" "/some/CustomFW" "-[^i] diff --git a/test/expect/cmd.cc-msvc-c-bad-cmd.result.txt b/test/expect/cmd.cc-msvc-c-bad-cmd.result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/expect/cmd.cc-msvc-c-bad-cmd.result.txt @@ -0,0 +1 @@ +1 diff --git a/test/expect/cmd.cc-msvc-c-bad-cmd.stderr.txt b/test/expect/cmd.cc-msvc-c-bad-cmd.stderr.txt new file mode 100644 index 0000000..fca19b3 --- /dev/null +++ b/test/expect/cmd.cc-msvc-c-bad-cmd.stderr.txt @@ -0,0 +1,3 @@ +^error: '--castxml-cc-msvc-c' compiler command failed: + + 'cc-msvc-c-bad-cmd' '-c' '-FoNUL' '.*/share/castxml/detect_vs.c diff --git a/test/expect/cmd.cc-msvc-c-src-c-E.stdout.txt b/test/expect/cmd.cc-msvc-c-src-c-E.stdout.txt new file mode 100644 index 0000000..04ac327 --- /dev/null +++ b/test/expect/cmd.cc-msvc-c-src-c-E.stdout.txt @@ -0,0 +1,2 @@ +^#define _MSC_VER 1600 +#define _WIN32 1$ diff --git a/test/expect/cmd.cc-msvc-c-src-c-cmd.stderr.txt b/test/expect/cmd.cc-msvc-c-src-c-cmd.stderr.txt new file mode 100644 index 0000000..fb9ae02 --- /dev/null +++ b/test/expect/cmd.cc-msvc-c-src-c-cmd.stderr.txt @@ -0,0 +1 @@ +"clang" .* "-[^i][^"]*" "[^-"][^"]*" "-isystem" "/some/include" "-isystem" "/some/other/include" "-[^i] -- cgit v0.12