class CKick::Project

This class represents a CMake project (as a main CMakeLists)

Constants

CMAKE_VERSION_MATCH

version match

NAME_MATCH

project name match pattern

Attributes

build_dir[R]

project build directory

dependencies[R]
root[R]

project root directory

subdirs[R]

each project CKick::SubDirectory

Public Class Methods

new(args) click to toggle source
  • args - project hash (directly the CKickfile parsed with keys as Symbol), must be a Hash

Input hash keys
  • :name - project name, must respect NAME_MATCH

  • :cmake_min_version - CMake minimum version (must be String), defaults to '3', must match CMAKE_VERSION_MATCH

  • :root - Project root directory, usually '.'

  • :build_dir - Project build directory, usually 'build'

  • :subdirs - subdirectories (in respect to CMake subdirectory() command), must be a Array of Hash passed to SubDirectory::new

  • :plugins - Array of Hash containing {:name => CKick::Plugin class name, :args => args for respective :initialize method }

# File lib/ckick/project.rb, line 44
def initialize args
  name = args[:name] || ""
  raise IllegalInitializationError, "name must be a non-empty string only containing alphanumeric characters" unless name.is_a?(String) && name.match(NAME_MATCH)

  min_v = args[:cmake_min_version] || '3'
  raise IllegalInitializationError, "cmake_min_version is non-String" unless min_v.is_a?(String)
  raise IllegalInitializationError, "cmake_min_version has non working pattern x or x.y or x.y.z" unless min_v.match(CMAKE_VERSION_MATCH)

  root = args[:root] || ""
  raise IllegalInitializationError, "root directory is non-String" unless root.is_a?(String)
  raise IllegalInitializationError, "root directory is empty" if root.empty?

  build_dir = args[:build_dir] || ""
  raise IllegalInitializationError, "build directory is non-String" unless build_dir.is_a?(String)
  raise IllegalInitializationError, "build directory is empty" if build_dir.empty?

  @name = name
  @cmake_min_version = min_v
  @root = root
  @build_dir = build_dir
  @dependencies = Dependencies.new(args[:dependencies] || {})

  @plugins = []
  args[:plugins].each do |plugin|
    @plugins << PluginDelegate.find(plugin)
  end

  @subdirs = []
  args[:subdirs].each do |subdir|
    @subdirs << SubDirectory.new(subdir)
  end

  @subdirs_initiated = false
  init_subdirs
end

Public Instance Methods

cmake() click to toggle source

main project's CMakeLists.txt content

# File lib/ckick/project.rb, line 129
def cmake
  append_plugin_paths

  res = "project(#{@name})\n" +
        "cmake_minimum_required(VERSION #{@cmake_min_version})\n\n"

  res << "set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)\n" \
         "set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)\n" \
         "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)\n\n"

  res << @dependencies.cmake << "\n\n"

  res << plugins_cmake << "\n\n" unless @plugins.empty?

  @subdirs.each do |dir|
    res << "add_subdirectory(#{dir.name})\n" if dir.has_cmake
  end

  res
end
create_structure() click to toggle source

creates the project CMake structure

# File lib/ckick/project.rb, line 102
def create_structure
  raise "SubDirectories have not been initiated" unless @subdirs_initiated

  run_plugins

  PathDelegate.create_directory path
  PathDelegate.write_file(path, "CMakeLists.txt", cmake)

  @subdirs.each do |subdir|
    subdir.create_structure
  end

  call_plugins
end
path() click to toggle source

project root directory path

# File lib/ckick/project.rb, line 97
def path
  @root
end
register_plugin(plugin=nil, &block) click to toggle source

register an additionnal CKick::Plugin or block

# File lib/ckick/project.rb, line 118
def register_plugin(plugin=nil, &block)
  raise ArgumentError, "" unless plugin.is_a?(::CKick::Plugin) || block

  if plugin.is_a?(::CKick::Plugin)
    @plugins << plugin
  elsif plugin.nil? && block
    @plugins << block
  end
end
set_name(name) click to toggle source

set the project name, must match NAME_MATCH

# File lib/ckick/project.rb, line 81
def set_name(name)
  raise BadProjectNameError, "project name must be a non-empty alphanumeric string" unless name.is_a?(String) && name.match(NAME_MATCH)
  @name = name
end
to_hash() click to toggle source

convert to Hash (to CKickfile)

# File lib/ckick/project.rb, line 92
def to_hash
  to_no_empty_value_hash.without(:subdirs_initiated)
end
to_s() click to toggle source

convert to String -> the project name as is

# File lib/ckick/project.rb, line 87
def to_s
  @name
end

Private Instance Methods

append_plugin_paths() click to toggle source

appends include path and library path by each CKick::Plugin#include and CKick::Plugin#lib

# File lib/ckick/project.rb, line 162
def append_plugin_paths
  @plugins.each do |plugin|
    plugin.include(self).each do |path|
      @dependencies.add_include path
    end
    plugin.lib(self).each do |path|
      @dependencies.add_lib path
    end
  end
end
call_plugins() click to toggle source

ran after structure creation (calls each CKick::Plugin#call)

# File lib/ckick/project.rb, line 181
def call_plugins
  @plugins.each do |plugin|
    plugin.call self
  end
end
init_subdirs() click to toggle source

called at the end of Project::new

# File lib/ckick/project.rb, line 153
def init_subdirs
  @subdirs.each do |subdir|
    subdir.__send__ :set_parent, path
  end

  @subdirs_initiated = true
end
plugins_cmake() click to toggle source

plugins CMakeLists.txt content section in main CMakeLists.txt content

# File lib/ckick/project.rb, line 188
def plugins_cmake
  res = "##ckick plugins section##\n"

  def plugin_name(plugin) #:nodoc:
    if plugin.respond_to?(:name)
      return plugin.name
    else
      return "<inline plugin>"
    end
  end

  @plugins.each do |plugin|
    res << "#ckick plugin: #{plugin_name(plugin)}\n"
    res << plugin.cmake << "\n" if plugin.respond_to? :cmake
  end

  res << "##end plugin section##"
end
run_plugins() click to toggle source

ran before structure creation (calls each CKick::Plugin#run)

# File lib/ckick/project.rb, line 174
def run_plugins
  @plugins.each do |plugin|
    plugin.run(self) if plugin.respond_to? :run
  end
end