Skip to content

Commit

Permalink
work in progress to only ask user if flags have changed. The check is…
Browse files Browse the repository at this point in the history
… not working fully yet.
  • Loading branch information
niosus committed Jul 10, 2016
1 parent 3418033 commit b0e1065
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 21 deletions.
1 change: 1 addition & 0 deletions .clang_complete
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
-I/usr/include/opencv
-I/home/igor/.config/sublime-text-3/Packages/EasyClangComplete
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 2.8)

project(blah)

include_directories(${PROJECT_SOURCE_DIR})
find_package(OpenCV)

include_directories(${PROJECT_SOURCE_DIR}
SYSTEM ${OpenCV_DIRS})

add_executable(main test.cpp)
61 changes: 41 additions & 20 deletions plugin/completion/flags_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FlagsManager:
_use_cmake = False
_flags_update_strategy = "ask"

cmake_mask = "cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON {}"
cmake_mask = 'cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON {path}'

CMAKE_FILE_NAME = "CMakeLists.txt"
CMAKE_DB_FILE_NAME = "compile_commands.json"
Expand Down Expand Up @@ -80,13 +80,25 @@ def get_flags(self, separate_includes):
compilation_db = FlagsManager.compile_cmake(
self._cmake_file)
if compilation_db:
flags_set = FlagsManager.flags_from_database(compilation_db)
new_flags = FlagsManager.flags_from_database(compilation_db)
new_clang_file_path = path.join(
self._cmake_file.folder(),
FlagsManager.CLANG_COMPLETE_FILE_NAME)
FlagsManager.write_flags_to_file(
flags_set, new_clang_file_path,
self._flags_update_strategy)
# there is no need to modify anything if the flags have not
# changed since we have last read them
curr_flags = set(FlagsManager.flags_from_clang_file(
file=File(new_clang_file_path),
separate_includes=False))
if len(new_flags.symmetric_difference(curr_flags)) > 0:
FlagsManager.write_flags_to_file(
new_flags, new_clang_file_path,
self._flags_update_strategy)
log.debug("'%s' is not equal to '%s' by %s so update",
new_flags, curr_flags,
new_flags.symmetric_difference(curr_flags))
else:
log.debug(" the flags have not changed so we don't "
"modify the .clang_complete file")
else:
log.warning(" could not get compilation database from cmake")

Expand All @@ -108,15 +120,23 @@ def get_flags(self, separate_includes):
@staticmethod
def compile_cmake(cmake_file):
import os
cmake_cmd = FlagsManager.cmake_mask.format(cmake_file.folder())
tempdir = path.join(Tools.get_temp_dir(), 'build')
import hashlib
cmake_cmd = FlagsManager.cmake_mask.format(path=cmake_file.folder())
unique_proj_str = hashlib.md5(
cmake_file.full_path().encode('utf-8')).hexdigest()
tempdir = path.join(
Tools.get_temp_dir(), 'cmake_builds', unique_proj_str)
if not path.exists(tempdir):
os.makedirs(tempdir)
try:
my_env = os.environ.copy()
# TODO: add variables that are otherwise missing
# my_env['CMAKE_PREFIX_PATH'] = '/home/igor/Code/catkin_ws/devel:/opt/ros/indigo'
output = subprocess.check_output(cmake_cmd,
stderr=subprocess.STDOUT,
shell=True,
cwd=tempdir)
cwd=tempdir,
env=my_env)
output_text = ''.join(map(chr, output))
except subprocess.CalledProcessError as e:
output_text = e.output.decode("utf-8")
Expand All @@ -131,23 +151,23 @@ def compile_cmake(cmake_file):
return File(database_path)

@staticmethod
def write_flags_to_file(flags_set, file_path, strategy):
def write_flags_to_file(new_flags, file_path, strategy):
if path.exists(file_path):
log.debug(" path already exists")
flag_strategy = FlagsManager.get_flags_strategy(strategy)
log.debug(" picked '%s' strategy.", flag_strategy)
if flag_strategy == "keep_old":
return
if flag_strategy == "merge":
# union of two flags sets
curr_flags = set(FlagsManager.flags_from_clang_file(
File(file_path), separate_includes=False))
# union
flags_set = flags_set.union(curr_flags)
new_flags = new_flags.union(curr_flags)
# unhandled is only "overwrite". "ask" is not possible here.
f = open(file_path, 'w')
# write file
f.seek(0)
f.write('\n'.join(flags_set) + '\n')
f.write('\n'.join(new_flags) + '\n')
f.close()

@staticmethod
Expand Down Expand Up @@ -186,11 +206,11 @@ def flags_from_database(database_file):
all_command_parts = command.split()
for (i, part) in enumerate(all_command_parts):
if part.startswith('-I') or part.startswith('-D'):
flags_set.add(part)
flags_set.add(part.strip())
continue
if part.startswith('-isystem'):
flags_set.add(
all_command_parts[i] + ' ' + all_command_parts[i + 1])
tmp = all_command_parts[i] + ' ' + all_command_parts[i + 1]
flags_set.add(tmp.strip())
continue
log.debug(" flags set: %s", flags_set)
return flags_set
Expand Down Expand Up @@ -223,22 +243,23 @@ def flags_from_clang_file(file, separate_includes):
content = f.readlines()
for line in content:
if line.startswith('-D'):
flags.append(line)
flags.append(line.strip())
elif line.startswith('-I'):
path_to_add = line[2:].rstrip()
path_to_add = line[2:].strip()
if path.isabs(path_to_add):
flags.append(mask.format(
'-I', path.normpath(path_to_add)))
else:
flags.append(mask.format(
'-I', path.join(folder, path_to_add)))
elif line.startswith('-isystem'):
path_to_add = line[8:].rstrip().strip()
path_to_add = line[8:].strip()
if path.isabs(path_to_add):
flags.append(mask.format(
'-isystem', path.normpath(path_to_add)))
'-isystem', path.normpath(path_to_add)).strip())
else:
flags.append(mask.format(
'-isystem', path.join(folder, path_to_add)))
'-isystem',
path.join(folder, path_to_add)).strip())
log.debug(" .clang_complete contains flags: %s", flags)
return flags

0 comments on commit b0e1065

Please sign in to comment.