-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default compiler standard #1720
Conversation
libcodechecker/analyze/log_parser.py
Outdated
test_file = temp_file + ('.c' if lang == 'c' else '.cpp') | ||
os.rename(temp_file, test_file) | ||
|
||
with open(test_file, 'w') as f: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use io.open
libcodechecker/analyze/log_parser.py
Outdated
executable = os.path.join(tempfile.gettempdir(), | ||
next(tempfile._get_candidate_names())) | ||
|
||
proc = subprocess.Popen([compiler, '-o', executable, test_file], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please handle Popen
exceptions in case the call fails.
libcodechecker/analyze/log_parser.py
Outdated
|
||
os.chmod(executable, stat.S_IXUSR) | ||
|
||
proc = subprocess.Popen([executable], stdout=subprocess.PIPE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please handle Popen
exceptions in case the call fails.
compiler_includes_dump_file)) | ||
remove_file_if_exists(os.path.join(output_path, | ||
compiler_target_dump_file)) | ||
global compiler_info_dump_file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of global variables, could you change it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I tried some other implementations, but every other solution was much uglier and boilerplate. So I left it like this, maybe we could figure out something more elegant later.
libcodechecker/analyze/log_parser.py
Outdated
proc = subprocess.Popen([executable], stdout=subprocess.PIPE) | ||
out, _ = proc.communicate() | ||
|
||
os.remove(test_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please handle exceptions if the files are already removed for some reason, or use the remove_file_if_exists
function.
libcodechecker/analyze/log_parser.py
Outdated
} | ||
""" | ||
|
||
err = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this named err
, the cpp standard argument will be stored in it.
1b2bec4
to
b6c960c
Compare
libcodechecker/analyze/log_parser.py
Outdated
if parseLogOptions.compiler_info_file is None: | ||
_, temp_file = tempfile.mkstemp() | ||
test_file = temp_file + ('.c' if lang == 'c' else '.cpp') | ||
os.rename(temp_file, test_file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think removing a temp file should be done in the following form:
_, temp_file = tempfile.mkstemp()
try:
...
finally:
remove_file_if_exists(temp_file)
remove_file_if_exists(test_file)
What do you think @gyorb?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using NamedTemporaryFile
in a with statement with a suffix (no renaming is needed) would be easier and it would remove the file when it is out of context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the temporary file handling.
b6c960c
to
eeebd03
Compare
@@ -127,16 +127,24 @@ def add_arguments_to_parser(parser): | |||
dest="compiler_includes_file", | |||
required=False, | |||
default=None, | |||
help="Read the compiler includes from the specified " | |||
"file rather than invoke the compiler " | |||
help="DEPRECATED. Read the compiler includes from the " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deprecated arguments used to have a wrapper somewhere which allowed setting them to behave with emitting a warning that a deprecated argument is used. I think this should be introduced again, or just simply the argument parser round (__handle
) written in a way that the user is warned about the deprecated argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to search this wrapper in the git history. However, I'd propose a new policy rule: if there are such changes which involve other parts of the source code requiring their change, and not in the scope of the current pull request, then a new issue should be registered, maybe by additionally providing the assignee. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class DeprecatedOptionAction(argparse.Action): |
Although yeah, the handling of this should be made more reusable and standard.
(Then again, argparse
should also be extended to allow broader cross-argument rules and dependencies for which we use __handle
...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure actually compiling something and executing it is the best approach? We could simply use a #pragma GCC error
preprocessor macro (both Clang and MSVC understand it too!) and splitting the compiler stderr
could also give us the information.
libcodechecker/analyze/log_parser.py
Outdated
"detector.") | ||
|
||
if os.path.isfile(exe): | ||
os.chmod(exe, stat.S_IXUSR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the user always have the permission to set these bits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of using preprocessing time error sounds good. Do you know any difference between #error
and #pragma GCC error
? Isn't the former one more standard?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The #pragma
version gives me different outputs with different compilers. g++
(5.5.0) seems not to understand it: error: invalid "#pragma GCC error" directive
.
By the way can we rely on the error message format between different compilers, or even same compiler and different versions? Wouldn't it complicate the parsing of this output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about #error
.
The output should be sufficiently small: CC_FOUND_STARDARD_VER|23
. On that, a simple regex can give us the answer, irrespective to whatever specific compiler and version is used.
Also, with regards to the temporary file: we could distribute the "prepared" C/C++ code as a resource with the CodeChecker install, instead of creating them at runtime. |
I tried to keep these C++ codes in separate files but it was not possible to reach them from the test code. |
@bruntib That is an ongoing issue (that the tests can rarely pull configuration and other stuff from the deployed environment), see #787. Until then, I think still putting these into separate files (e.g. |
The idea behind this solution was that |
Was just an idea, this workaround is good enough for me. However, I think it would be better if the code, if it stays in the Python file, gets moved out of the function's scope? It is... essentially a |
The outer scope is global scope which we try to fight against, even in this ticket for another variable. Would you suggest to place it there? By the way in an other language I would choose |
eeebd03
to
23de4b8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gcc accepts -std=c++11 in the following forms
-std=c++11
--std=c++11
--std c++11
Only the first form is handled.
Please handle the other variations too.
@@ -136,6 +136,10 @@ def construct_analyzer_cmd(self, result_handler): | |||
|
|||
analyzer_cmd.extend(self.buildaction.compiler_includes) | |||
|
|||
if not next((x for x in analyzer_cmd if x.startswith('-std=')), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gcc accepts -std=c++11 in the following forms
-std=c++11
--std=c++11
--std c++11
Only the first form is handled.
Please handle the other variations too.
9ed0aa6
to
217754b
Compare
217754b
to
37ce3ec
Compare
The --compiler-includes and --compiler-target flags are deprecated under "CodeChecker analyze" command, --compiler-info is introduced instead. The new compiler info dump file contains the information of these two merged into one JSON, however, the files with the old format still can be used for supporting reverse compatibility.
37ce3ec
to
ce6c56f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please extend the New features tab with this feature:
C/C++ standard auto detection
Detect automatically which C/C++ standard was used for compilation by gcc and pass the relevant option to Clang (e.g. -std=c++11)
ce6c56f
to
133b01d
Compare
133b01d
to
44fc7f7
Compare
Some implicit information, like implicit include paths or compiler targets, may depend on the used C/C++ language standard. This can be provided by "-std=" flag. However, in some cases this flag is not used and has a default value which depends on the compiler binary. In this commit the intention is to detect this default language standard version.
44fc7f7
to
fcd5e85
Compare
No description provided.