Source code for bob.extension.cmake

import os

HEADER = (
  '\n'
  '# For both C and C++\n'
  'set(COMMON_FLAGS "-pedantic -Wall")\n'
  'if (WIN32)\n'
  '  set(COMMON_FLAGS "-D_WIN32_WINNT=0x501") # Set min. Windows version to XP\n'
  'else(WIN32)\n'
  '  set(COMMON_FLAGS "${COMMON_FLAGS} -pthread")\n'
  'endif (WIN32)\n'
  'if (NOT CMAKE_COMPILER_IS_GNUCC)\n'
  '  # Then, it must be clang/clang++\n'
  '  set(COMMON_FLAGS "${COMMON_FLAGS} -Qunused-arguments")\n'
  'endif ()\n'
  '\n'
  '# Force __LP64__ scheme on Mac OSX\n'
  'if(APPLE)\n'
  '  set(CMAKE_MACOSX_RPATH TRUE CACHE BOOL "Enables the MACOS_RPATH feature for MacOSX builds" FORCE)\n'
  '  set(COMMON_FLAGS "${COMMON_FLAGS} -m64")\n'
  'endif(APPLE)\n'
  '\n'
  '# For both RELEASE and DEBUG builds\n'
  'if(APPLE AND CMAKE_COMPILER_IS_GNUCC)\n'
  '  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.4")\n'
  '    message(FATAL_ERROR "Minimum GCC version required on OSX is 4.4, but you have ${CMAKE_CXX_COMPILER_VERSION}")\n'
  '  endif()\n'
  '  set(COMMON_FLAGS "${COMMON_FLAGS} -Wno-long-long -Wno-variadic-macros")\n'
  '  set(COMMON_CXX_FLAGS "-std=c++0x")\n'
  '  set(COMMON_C_FLAGS "-std=c99")\n'
  'elseif(WIN32)\n'
  '  set(COMMON_CXX_FLAGS "-std=gnu++0x")\n'
  '  set(COMMON_C_FLAGS "-std=gnu99")\n'
  'else()\n'
  '  set(COMMON_CXX_FLAGS "-std=c++0x")\n'
  '  set(COMMON_C_FLAGS "-std=c99")\n'
  'endif()\n'
  '\n'
  '# These are used in type checks for cmake, be aware and don\'t change those\n'
  'set(CMAKE_CXX_FLAGS "${COMMON_CXX_FLAGS} ${COMMON_FLAGS} $ENV{CXXFLAGS} $ENV{CPPFLAGS}" CACHE STRING "Flags used by the compiler during release builds" FORCE)\n'
  'set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} ${COMMON_FLAGS} $ENV{CFLAGS} $ENV{CPPFLAGS}" CACHE STRING "Flags used by the compiler during release builds" FORCE)\n'
  '\n'
  'set(BUILD_SHARED_LIBS "ON" CACHE BOOL "Build shared libs")\n\n'
)


[docs]class CMakeListsGenerator: """Generates a CMakeLists.txt file for the given sources, include directories and libraries.""" def __init__(self, name, sources, target_directory, version = '1.0.0', include_directories = [], system_include_directories=[], libraries = [], library_directories = [], macros = []): """Initializes the CMakeLists generator. Keyword parameters: name : string The name of the library to generate sources : [string] The list of source files that should be compiled with CMake target_directory : [string] The directory where the final library should be placed version The version of the library, major.minor.patch include_directories : [string] A list of include directories required to compile the ``sources`` system_include_directories : [string] A list of include directories required to compile the ``sources``, which will be added as SYSTEM includes libraries : [string] A list of libraries to be linked into the generated library library_directories : [string] A list of directories, where the ``libraries`` can be found. Note that the order of this list might be important. macros : [(string, string)] A list of preprocessor defines ``name=value`` that will be added to the compilation """ self.name = name self.sources = sources self.target_directory = target_directory self.version = version self.includes = include_directories self.system_includes = system_include_directories self.libraries = libraries self.library_directories = library_directories self.macros = macros
[docs] def generate(self, source_directory, build_directory): """Generates the CMakeLists.txt file in the given directory.""" # check if CFLAGS or CXXFLAGS are set, and set them if not if 'CFLAGS' not in os.environ: os.environ['CFLAGS'] = '-O3 -g0 -DNDEBUG -mtune=native' if 'CXXFLAGS' not in os.environ: os.environ['CXXFLAGS'] = '-O3 -g0 -DNDEBUG -mtune=native' source_dir = os.path.realpath(source_directory) # source and target in different directories -> use absolute paths source_files = [os.path.join(source_dir, s) for s in self.sources] filename = os.path.join(build_directory, "CMakeLists.txt") with open(filename, 'w') as f: f.write('# WARNING! This file is automatically generated. Do not change its contents.\n\n') f.write('cmake_minimum_required(VERSION 2.8)\n') f.write('project(%s)\n' % self.name) f.write(HEADER) # add include directories for directory in self.includes: f.write('include_directories(%s)\n' % directory) for directory in self.system_includes: f.write('include_directories(SYSTEM %s)\n' % directory) # add link directories # TODO: handle RPATH and Non-RPATH differently (don't know, how, though) for directory in self.library_directories: f.write('link_directories(%s)\n' % directory) # add defines for macro in self.macros: f.write('add_definitions(-D%s=%s)\n' % macro) # compile this library f.write('\nadd_library(${PROJECT_NAME} \n\t' + "\n\t".join(source_files) + '\n)\n') f.write('set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)\n') f.write('set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY %s)\n\n' % self.target_directory) # link libraries if self.libraries: f.write('target_link_libraries(${PROJECT_NAME} %s)\n\n' % " ".join(self.libraries))