diff --git a/scripts/yujin_init_build b/scripts/yujin_init_build index 7847390..0bcfdfc 100755 --- a/scripts/yujin_init_build +++ b/scripts/yujin_init_build @@ -1,8 +1,13 @@ #!/usr/bin/env python +import sys import yujin_tools - -if __name__ == "__main__": - yujin_tools.init_build() - +import yujin_tools.console as console + +if __name__ == '__main__': + try: + sys.exit(yujin_tools.init_build()) + except Exception as e: + console.logerror(str(e)) + sys.exit(1) diff --git a/setup.py b/setup.py index 3b49a8a..53f4a9d 100755 --- a/setup.py +++ b/setup.py @@ -32,7 +32,10 @@ 'templates/init_build/gnome-terminal', 'templates/init_build/eclipse', 'toolchains/arm-generic-gnueabi.cmake', - 'platforms/arm1176jzf-s.cmake' + 'platforms/default.cmake', + 'platforms/generic/*', + 'platforms/arm/*', + 'platforms/intel/*', ]}, author = "Daniel Stonier", author_email = "d.stonier@gmail.com", diff --git a/src/yujin_tools/cmake/config.cmake b/src/yujin_tools/cmake/config.cmake index a2d57ae..b9981ca 100644 --- a/src/yujin_tools/cmake/config.cmake +++ b/src/yujin_tools/cmake/config.cmake @@ -1,3 +1,8 @@ + +############################################################################### +# Build Configuration +############################################################################### + ########################### # Parameterised Variables ########################### @@ -11,7 +16,7 @@ set(CMAKE_BUILD_TYPE %(config_build_type)s CACHE STRING "Build mode type.") set(CMAKE_INSTALL_PREFIX %(config_install_prefix)s CACHE PATH "Install root location.") set(CMAKE_PREFIX_PATH "${UNDERLAY_ROOTS}" CACHE PATH "semi-colon separated software/ros workspace paths.") # We use CMAKE_USER_MAKE_RULES_OVERRIDE to configure CMAKE_CXX_FLAGS_INIT () -set(YUJIN_CXX_FLAGS_INIT "" CACHE STRING "Initial flags that get passed to CMAKE_CXX_FLAGS via the cmake override file.") +set(YUJIN_CXX_FLAGS_INIT "${PLATFORM_CXX_FLAGS}" CACHE STRING "Initial flags that get passed to CMAKE_CXX_FLAGS via the cmake override file.") set(CMAKE_USER_MAKE_RULES_OVERRIDE "%(config_override_file)s" CACHE PATH "User override file for setting global compiler flags.") ########################### diff --git a/src/yujin_tools/common.py b/src/yujin_tools/common.py index 8fef3a8..2ee2f9c 100644 --- a/src/yujin_tools/common.py +++ b/src/yujin_tools/common.py @@ -7,8 +7,6 @@ import os import sys import re -#import tempfile -import shutil # Local imports import console import python_setup @@ -45,7 +43,8 @@ def get_underlays_list_from_config_cmake(): ''' f = open('config.cmake') for line in f: - m = re.search('^set\(UNDERLAY_ROOTS "(.*)"', line) + # use .*? where ? makes the match non-greedy + m = re.search('^set\(UNDERLAY_ROOTS "(.*?)"', line) if m: return m.group(1).split(';') return [] diff --git a/src/yujin_tools/init_build.py b/src/yujin_tools/init_build.py index bc26e5b..8940801 100644 --- a/src/yujin_tools/init_build.py +++ b/src/yujin_tools/init_build.py @@ -36,13 +36,13 @@ def help_string(): def parse_arguments(): parser = argparse.ArgumentParser(description=help_string(), formatter_class=RawTextHelpFormatter) - parser.add_argument('dir', nargs='?', default="./", help='directory to use for the parallel development space [./]') + parser.add_argument('dir', nargs='?', default=".", help='directory to use for the parallel development space [./]') parser.add_argument('sources', nargs='?', default="src", help='directory where the sources reside [./src]') parser.add_argument('-r', '--release', action='store_true', help='build in Release mode instead of RelWithDebugSymbols [false]') parser.add_argument('-i', '--install', action='store', default='/not_set_directory', help='installation location [workspace/install]') - parser.add_argument('-u', '--underlays', action='store', default='/opt/ros/groovy', help='semi-colon list of catkin workspaces to utilise [/opt/ros/groovy]') + parser.add_argument('-u', '--underlays', action='store', default='', help='semi-colon list of catkin workspaces to utilise [/opt/ros/groovy]') parser.add_argument('-t', '--toolchain', action='store', default='', help='toolchain cmake module to load []') - parser.add_argument('-p', '--platform', action='store', default='', help='platform cmake cache module to load []') + parser.add_argument('-p', '--platform', action='store', default='default', help='platform cmake cache module to load [default]') parser.add_argument('--list-toolchains', action='store_true', help='list all currently available toolchain modules [false]') parser.add_argument('--list-platforms', action='store_true', help='list all currently available platform modules [false]') parser.add_argument('--track', action='store', default=None, help='retrieve rosinstalls relevant to this track [groovy|hydro][groovy]') @@ -108,48 +108,65 @@ def instantiate_config_cmake(platform_content, build_path, config_build_type, co config_cmake_file = os.path.join(build_path, "config.cmake") try: f = open(config_cmake_file, 'w') + f.write(platform_content.encode('utf-8')) f.write(contents.encode('utf-8')) finally: f.close() def print_build_details(build_dir, source_dir, install_prefix, build_type, underlays, name, toolchain, platform): - console.pretty_println("************************** Parallel Buildspace Details ***************************", console.bold) - console.pretty_print("Build directory : ", console.cyan) + console.pretty_println("\n************************** Parallel Buildspace Details ***************************", console.bold) + console.pretty_print(" -- Build directory : ", console.cyan) console.pretty_println(build_dir, console.yellow) - console.pretty_print("Source directory: ", console.cyan) + console.pretty_print(" -- Source directory: ", console.cyan) console.pretty_println(source_dir, console.yellow) - console.pretty_print("Install prefix : ", console.cyan) + console.pretty_print(" -- Install prefix : ", console.cyan) console.pretty_println(install_prefix, console.yellow) - console.pretty_print("Build Type : ", console.cyan) + console.pretty_print(" -- Build Type : ", console.cyan) console.pretty_println(build_type, console.yellow) - console.pretty_print("Underlays : ", console.cyan) + console.pretty_print(" -- Underlays : ", console.cyan) console.pretty_println(underlays, console.yellow) - console.pretty_print("Eclipse Name : ", console.cyan) + console.pretty_print(" -- Eclipse Name : ", console.cyan) console.pretty_println(name, console.yellow) if not toolchain == "": - console.pretty_print("Toolchain : ", console.cyan) + console.pretty_print(" -- Toolchain : ", console.cyan) console.pretty_println(toolchain, console.yellow) if not platform == "": - console.pretty_print("Platform : ", console.cyan) + console.pretty_print(" -- Platform : ", console.cyan) console.pretty_println(platform, console.yellow) - console.pretty_println("**********************************************************************************", console.bold) + console.pretty_println("**********************************************************************************\n", console.bold) def list_toolchains(): - console.pretty_println("******************************** Toolchain List **********************************", console.bold) + console.pretty_println("\n******************************** Toolchain List **********************************", console.bold) for (unused_dirpath, unused_dirname, filenames) in os.walk(os.path.join(os.path.dirname(__file__), 'toolchains')): for filename in filenames: - print(" -- %s" % os.path.splitext(os.path.basename(filename))[0]) - console.pretty_println("**********************************************************************************", console.bold) + console.pretty_println(" -- %s" % os.path.splitext(os.path.basename(filename))[0], console.cyan) + console.pretty_println("**********************************************************************************\n", console.bold) + + +def get_platforms(): + platforms = {} + for (dirpath, unused_dirname, filenames) in os.walk(os.path.join(os.path.dirname(__file__), 'platforms')): + family = os.path.basename(dirpath) + if family != 'platforms': + platforms[family] = [] + # we are in a subdirectory, i.e. a family, good! + for filename in filenames: + platforms[family].append(os.path.splitext(filename)[0]) # leave off the .cmake extension + return platforms def list_platforms(): - console.pretty_println("********************************* Platform List **********************************", console.bold) - for (unused_dirpath, unused_dirname, filenames) in os.walk(os.path.join(os.path.dirname(__file__), 'platforms')): - for filename in filenames: - print(" -- %s" % os.path.splitext(os.path.basename(filename))[0]) - console.pretty_println("**********************************************************************************", console.bold) + console.pretty_println("\n********************************* Platform List **********************************", console.bold) + platforms = get_platforms() + console.pretty_println("Official:", console.bold) + for family in platforms: + for platform in platforms[family]: + console.pretty_print(" -- %s/" % family, console.cyan) + console.pretty_println("%s" % platform, console.yellow) + console.pretty_println("Custom:", console.bold) + console.pretty_println("**********************************************************************************\n", console.bold) def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt/ros/groovy", install_prefix_="./install", release_=False, toolchain_="", platform_=""): @@ -175,8 +192,7 @@ def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt if not os.path.isdir(build_dir): # remember ./ is a valid build dir, even if it's not populated yet os.mkdir(build_dir) else: - console.logerror("This build directory is already initialised") - sys.exit(1) + raise RuntimeError("This build directory is already initialised") ########################## # Source directory @@ -184,15 +200,12 @@ def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt source_dir = os.path.abspath(source_dir_) build_source_dir = os.path.join(build_dir, 'src') if not os.path.isdir(source_dir): - console.logerror("Specified source space does not exist [" + source_dir + "]") - sys.exit(1) + raise RuntimeError("Specified source space does not exist [" + source_dir + "]") if not os.path.isfile(os.path.join(source_dir, ".rosinstall")): - console.logerror("Could not find a valid source folder (must contain a .rosinstall file therein)'") - sys.exit(1) + raise RuntimeError("Could not find a valid source folder (must contain a .rosinstall file therein)'") if os.path.exists(build_source_dir): if not source_dir == build_source_dir: - console.error("The build directory already has a ./src directory which doesn't match the desired source directory [%s]" % source_dir) - sys.exit(1) + raise RuntimeError("The build directory already has a ./src directory which doesn't match the desired source directory [%s]" % source_dir) else: os.mkdir(build_source_dir) source_subdirectories = os.walk(source_dir).next()[1] @@ -206,8 +219,8 @@ def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt env_underlays = os.environ['CMAKE_PREFIX_PATH'] except KeyError: env_underlays = "" - underlays_list = underlays_.split(';') - env_underlays_list = env_underlays.split(':') + underlays_list = [underlay for underlay in underlays_.split(';') if underlay] + env_underlays_list = [underlay for underlay in env_underlays.split(':') if underlay] for underlay in env_underlays_list: if underlay not in underlays_list: underlays_list.append(underlay) @@ -230,11 +243,10 @@ def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt if os.path.isfile(os.path.join("/opt/ros/%s" % default_track, 'share', 'catkin', 'cmake', 'toplevel.cmake')): catkin_toplevel = os.path.join("/opt/ros/%s" % default_track, 'share', 'catkin', 'cmake', 'toplevel.cmake') unused_catkin_python_path = os.path.join("/opt/ros/%s" % default_track, 'lib', 'python2.7', 'dist-packages') - console.pretty_println("No catkin found, adding the default track underlay (use yujin_tools_settings to change) [/opt/ros/%s]" % default_track) + console.pretty_println("No catkin found, adding the default track underlay (use yujin_tools_settings to change) [/opt/ros/%s]" % default_track, console.cyan) underlays_list.append("/opt/ros/%s" % default_track) else: - console.logerror("Could not find an underlying catkin installation.") - sys.exit(1) + raise RuntimeError("Could not find an underlying catkin installation.") common.create_symlink(catkin_toplevel, os.path.join(build_source_dir, "CMakeLists.txt")) underlays = ';'.join(underlays_list) @@ -266,10 +278,27 @@ def init_configured_build(build_dir_="./", source_dir_="./src", underlays_="/opt # Platform ########################## platform_content = "" - if not platform_ == "": - platforms_dir = os.path.join(os.path.dirname(__file__), 'platforms') - if os.path.isfile(os.path.join(platforms_dir, platform_ + ".cmake")): - shutil.copy(os.path.join(platforms_dir, platform_ + ".cmake"), os.path.join(build_dir, "platform.cmake")) + if not platform_ == "default": + tmp_list = platform_.split('/') + if len(tmp_list) != 2: + raise RuntimeError("Platform specification invalid, must be / [%s]" % platform_) + family = tmp_list[0] + platform = tmp_list[1] + platforms = get_platforms() + try: + if not platform in platforms[family]: + raise RuntimeError("Platform %s for family %s not available." % (family, platform)) + except KeyError: + raise RuntimeError("No platforms available for family %s" % family) + platform_file = os.path.join(os.path.dirname(__file__), 'platforms', platform_ + ".cmake") + if os.path.isfile(platform_file): + f = open(platform_file, 'r') + try: + platform_content = f.read() + finally: + f.close() + else: + raise RuntimeError("Platform configuration not available [%s]" % platform_) ########################## # Cache @@ -297,8 +326,8 @@ def init_build(): ########################## if args.list_toolchains: list_toolchains() - sys.exit(0) + return if args.list_platforms: - list_toolchains() - sys.exit(0) + list_platforms() + return init_configured_build(args.dir, args.sources, args.underlays, args.install, args.release, args.toolchain, args.platform) diff --git a/src/yujin_tools/init_workspace.py b/src/yujin_tools/init_workspace.py index 86f56b8..efdff3b 100644 --- a/src/yujin_tools/init_workspace.py +++ b/src/yujin_tools/init_workspace.py @@ -9,15 +9,12 @@ import urlparse import yaml import urllib2 -import shutil ############################################################################## # Local imports ############################################################################## -from .init_build import init_configured_build import console -import common import settings ############################################################################## diff --git a/src/yujin_tools/make.py b/src/yujin_tools/make.py index bea4fc2..c77ad49 100644 --- a/src/yujin_tools/make.py +++ b/src/yujin_tools/make.py @@ -21,7 +21,6 @@ import console import common -import python_setup import catkin_make.terminal_color as terminal_color from catkin_make.terminal_color import fmt @@ -137,7 +136,9 @@ def make_main(): # Hack for catkin-python ######################### underlays_list = common.get_underlays_list_from_config_cmake() + print("Underlay List") print underlays_list + print("Underlay List") unused_catkin_toplevel, catkin_python_path = common.find_catkin(underlays_list) env = os.environ.copy() diff --git a/src/yujin_tools/platforms/arm/arm1176jzf-s.cmake b/src/yujin_tools/platforms/arm/arm1176jzf-s.cmake new file mode 100644 index 0000000..2f5df89 --- /dev/null +++ b/src/yujin_tools/platforms/arm/arm1176jzf-s.cmake @@ -0,0 +1,12 @@ +############################################################################### +# Family : arm +# Platform : arm1176jzf-s +############################################################################### + +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "arm" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "arm1176jzf-s" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +set(PLATFORM_CXX_FLAGS "-march=armv6 -mtune=arm1176jzf-s -pipe -mfloat-abi=softfp -mfpu=vfp" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.") diff --git a/src/yujin_tools/platforms/arm1176jzf-s.cmake b/src/yujin_tools/platforms/arm1176jzf-s.cmake deleted file mode 100644 index e69de29..0000000 diff --git a/src/yujin_tools/platforms/default.cmake b/src/yujin_tools/platforms/default.cmake new file mode 100644 index 0000000..b2987b5 --- /dev/null +++ b/src/yujin_tools/platforms/default.cmake @@ -0,0 +1,15 @@ +############################################################################### +# Family : generic +# Platform : vanilla +############################################################################### +# +# This is a special platform configuration in as much as its not special, just +# represents empty defaults. +# +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "generic" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "vanilla" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +set(PLATFORM_CXX_FLAGS "" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.") diff --git a/src/yujin_tools/platforms/generic/native.cmake b/src/yujin_tools/platforms/generic/native.cmake new file mode 100644 index 0000000..4eac341 --- /dev/null +++ b/src/yujin_tools/platforms/generic/native.cmake @@ -0,0 +1,13 @@ +############################################################################### +# Family : generic +# Platform : native +############################################################################### + +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "generic" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "native" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +# See here http://en.gentoo-wiki.com/wiki/Safe_Cflags for cpu type. +set(PLATFORM_CXX_FLAGS "-march=native -pipe" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.") diff --git a/src/yujin_tools/platforms/intel/atom330.cmake b/src/yujin_tools/platforms/intel/atom330.cmake new file mode 100644 index 0000000..e4654de --- /dev/null +++ b/src/yujin_tools/platforms/intel/atom330.cmake @@ -0,0 +1,15 @@ +############################################################################### +# Family : intel +# Platform : atom330 +############################################################################### + +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "intel" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "atom330" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +# Refer to http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel for cpu type. +# Refer to http://en.gentoo-wiki.com/wiki/Safe_Cflags#General_Information_on_CFLAGS. +# From gcc 4.5+ we can start using -march=atom -mtune=atom +set(PLATFORM_CXX_FLAGS "-march=prescott -mtune=generic -pipe -fomit-frame-pointer -mfpmath=sse -mmmx -msse -msse2 -mssse3" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.") diff --git a/src/yujin_tools/platforms/intel/atomn270.cmake b/src/yujin_tools/platforms/intel/atomn270.cmake new file mode 100644 index 0000000..3cf5e8f --- /dev/null +++ b/src/yujin_tools/platforms/intel/atomn270.cmake @@ -0,0 +1,15 @@ +############################################################################### +# Family : intel +# Platform : atomn270 +############################################################################### + +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "intel" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "atomn270" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +# Refer to http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel for cpu type. +# Refer to http://en.gentoo-wiki.com/wiki/Safe_Cflags#General_Information_on_CFLAGS. +# From gcc 4.5+ we can start using -march=atom -mtune=atom +set(PLATFORM_CXX_FLAGS "-march=core2 -mtune=generic -pipe -fomit-frame-pointer -mfpmath=sse -mmmx -mssse3" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.") diff --git a/src/yujin_tools/platforms/intel/i5.cmake b/src/yujin_tools/platforms/intel/i5.cmake new file mode 100644 index 0000000..60e5de6 --- /dev/null +++ b/src/yujin_tools/platforms/intel/i5.cmake @@ -0,0 +1,12 @@ +############################################################################### +# Family : intel +# Platform : i5 +############################################################################### + +# Some useful custom variables that uniquely define this platform module +set(PLATFORM_FAMILY "intel" CACHE STRING "Platform family, usually referring to intel/arm etc.") +set(PLATFORM_NAME "i5" CACHE STRING "Platform name, usually referring to the cpu architecture.") + +# Flags +set(PLATFORM_CXX_FLAGS "-march=core2 -mfpmath=sse -msse4 -pipe -mcx16 -mmmx -mpopcnt -msahf" CACHE STRING "Compile flags specific to this platform.") +set(PLATFORM_LINK_FLAGS "" CACHE STRING "Link flags specific to this platform.")