Preparing changes to use automatic CMakeFiles also in the ROS projects. (#48)

master
Holger Rapp 2016-10-12 17:03:46 +02:00 committed by GitHub
parent be813a06fe
commit 8f64860b5d
2 changed files with 51 additions and 33 deletions

View File

@ -16,22 +16,23 @@ include(CMakeParseArguments)
macro(_parse_arguments ARGS)
set(OPTIONS
USES_BOOST
USES_CERES
USES_EIGEN
USES_GFLAGS
USES_GLOG
USES_GLOG
USES_LUA
USES_BOOST
USES_WEBP
USES_GLOG
USES_GFLAGS
)
# Options only used by projects using Cartographers cmake files.
list(APPEND OPTIONS
USES_CARTOGRAPHER
USES_ROS
USES_ZLIB
USES_PCL
USES_ROS
USES_YAMLCPP
USES_ZLIB
)
set(ONE_VALUE_ARG )
set(MULTI_VALUE_ARGS SRCS HDRS DEPENDS)
@ -108,6 +109,10 @@ macro(_common_compile_stuff VISIBILITY)
endforeach()
endif()
if(ARG_USES_YAMLCPP)
target_link_libraries("${NAME}" yaml-cpp)
endif()
set_target_properties(${NAME} PROPERTIES
COMPILE_FLAGS ${TARGET_COMPILE_FLAGS})
@ -165,17 +170,6 @@ function(google_combined_library NAME)
DEPENDS ${ARG_SRCS}
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_BINARY_DIR} -I
${CMAKE_BINARY_DIR} ${REWRITTEN_PROTO}
DEPENDS ${REWRITTEN_PROTO}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM
)
# Just a dummy library, we will overwrite its output directly after again
# with its POST_BUILD step.
google_library(${NAME}
@ -273,6 +267,7 @@ function(google_library NAME)
STATIC
${ARG_SRCS} ${ARG_HDRS}
)
set_property(TARGET "${NAME}" PROPERTY POSITION_INDEPENDENT_CODE ON)
# Update the global variable that contains all static libraries.
SET(ALL_LIBRARIES "${ALL_LIBRARIES};${NAME}" CACHE INTERNAL "ALL_LIBRARIES")

View File

@ -19,6 +19,7 @@
import os
from os import path
import re
import argparse
def MakeRelative(filename, directory):
@ -72,20 +73,20 @@ class Target(object):
return "\n".join(lines)
def ExtractCartographerIncludes(source):
def ExtractProjectIncludes(project_name, source):
"""Returns all locally included files."""
includes = set()
for line in open(MaybeUseCmakeFile(source)):
if source.endswith(".proto"):
match = re.match(r'^import "(cartographer/[^"]+)', line)
match = re.match(r'^import "(' + project_name + r'/[^"]+)', line)
else:
match = re.match(r'^#include "(cartographer/[^"]+)"', line)
match = re.match(r'^#include "(' + project_name + r'/[^"]+)"', line)
if match:
includes.add(match.group(1))
return includes
def ExtractUses(source):
def ExtractUses(project_name, source):
"""Finds the options for the third_party libraries used."""
uses = set()
for line in open(MaybeUseCmakeFile(source)):
@ -99,10 +100,21 @@ def ExtractUses(source):
uses.add("USES_GLOG")
if re.match(r'^#include "gflags/', line):
uses.add("USES_GFLAGS")
if re.match(r"^#include <boost/", line):
if re.match(r'^#include ["<]boost/', line):
uses.add("USES_BOOST")
if re.match(r'^#include "webp/', line):
if re.match(r'^#include ["<]webp/', line):
uses.add("USES_WEBP")
if re.match(r'^#include ["<]pcl/', line):
uses.add("USES_PCL")
if re.match(r'^#include ["<]ros/', line):
uses.add("USES_ROS")
if re.match(r'^#include "[a-zA-Z]*_msgs/', line):
uses.add("USES_ROS")
if re.match(r'^#include ["<]yaml-cpp/', line):
uses.add("USES_YAMLCPP")
if project_name != "cartographer":
if re.match(r'^#include ["<]cartographer/', line):
uses.add("USES_CARTOGRAPHER")
return uses
@ -130,13 +142,20 @@ def ReadFileWithoutGoogleTargets(filename):
yield line.rstrip()
def ParseArgs():
p = argparse.ArgumentParser(
description="Automatically update cMakeFiles using build conventions.")
p.add_argument("root", type=str, help="Source directory.")
return p.parse_args()
def main():
root_directory = os.path.realpath(
os.path.join(os.path.dirname(__file__), os.path.pardir, "cartographer"))
args = ParseArgs()
targets_by_src = {}
targets = []
base_directory = path.realpath(path.join(root_directory, path.pardir))
project_name = os.path.basename(args.root)
base_directory = path.realpath(path.join(args.root, path.pardir))
directories = set()
def AddTarget(target_type, name, directory, srcs, hdrs):
@ -152,14 +171,16 @@ def main():
targets_by_src[proto_stem + ".pb.cc"] = target
directories.add(directory)
for (directory, sources) in FindSourceFiles(root_directory):
for (directory, sources) in FindSourceFiles(args.root):
module_name = path.relpath(directory,
path.realpath(root_directory)).replace("/", "_")
path.realpath(args.root)).replace("/", "_")
prepend_module_name = lambda s: (module_name + "_" + s) if module_name != "." else s
headers = set(fn for fn in sources if fn.endswith(".h"))
sources -= headers
for h in sorted(headers):
srcs = []
name = module_name + "_" + path.basename(path.splitext(h)[0])
name = prepend_module_name(path.basename(path.splitext(h)[0]))
cc_file = path.splitext(h)[0] + ".cc"
if cc_file in sources:
sources.remove(cc_file)
@ -169,13 +190,13 @@ def main():
tests = set(fn for fn in sources if fn.endswith("_test.cc"))
sources -= tests
for c in sorted(tests):
name = module_name + "_" + path.basename(path.splitext(c)[0])
name = prepend_module_name(path.basename(path.splitext(c)[0]))
AddTarget("google_test", name, directory, [c], [])
protos = set(fn for fn in sources if fn.endswith(".proto"))
sources -= protos
for c in sorted(protos):
name = module_name + "_" + path.basename(path.splitext(c)[0])
name = prepend_module_name(path.basename(path.splitext(c)[0]))
AddTarget("google_proto_library", name, directory, [c], [])
mains = set(fn for fn in sources if fn.endswith("_main.cc"))
@ -185,7 +206,7 @@ def main():
# 'cartographer' to distinguish them after installation. So,
# 'io/asset_writer_main.cc' will generate a binary called
# 'cartographer_asset_writer'.
name = 'cartographer_' + path.basename(path.splitext(c)[0][:-5])
name = "cartographer_" + path.basename(path.splitext(c)[0][:-5])
AddTarget("google_binary", name, directory, [c], [])
assert (not sources), "Remaining sources without target: %s" % sources
@ -195,12 +216,14 @@ def main():
targets_in_directory = [t for t in targets if t.directory == directory]
for target in targets_in_directory:
for src in target.srcs + target.hdrs:
for header in ExtractCartographerIncludes(src):
for header in ExtractProjectIncludes(project_name, src):
dependant = targets_by_src[header]
if dependant.name == target.name:
continue
target.depends.add(dependant.name)
target.uses.update(ExtractUses(src))
target.uses.update(ExtractUses(project_name, src))
if target.type is "google_test" and "USES_ROS" in target.uses:
target.type = "google_catkin_test"
cmake_file = path.join(directory, "CMakeLists.txt")
lines = list(ReadFileWithoutGoogleTargets(cmake_file))