ckick 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE +373 -0
- data/README.md +20 -0
- data/Rakefile +6 -0
- data/bin/ckick +84 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ckick.gemspec +27 -0
- data/lib/ckick.rb +54 -0
- data/lib/ckick/array.rb +19 -0
- data/lib/ckick/cflag.rb +15 -0
- data/lib/ckick/ckickfile.rb +11 -0
- data/lib/ckick/compiler_flag.rb +39 -0
- data/lib/ckick/cxxflag.rb +15 -0
- data/lib/ckick/dependencies.rb +72 -0
- data/lib/ckick/executable.rb +23 -0
- data/lib/ckick/find_plugin.rb +25 -0
- data/lib/ckick/hash.rb +33 -0
- data/lib/ckick/hash_elements.rb +51 -0
- data/lib/ckick/hashable.rb +44 -0
- data/lib/ckick/include_path.rb +19 -0
- data/lib/ckick/library.rb +37 -0
- data/lib/ckick/library_link.rb +32 -0
- data/lib/ckick/library_path.rb +19 -0
- data/lib/ckick/nil_class.rb +8 -0
- data/lib/ckick/path.rb +26 -0
- data/lib/ckick/path_delegate.rb +29 -0
- data/lib/ckick/plugin.rb +47 -0
- data/lib/ckick/plugin/clang_complete.rb +19 -0
- data/lib/ckick/plugin/gtest.rb +44 -0
- data/lib/ckick/plugin/resource/build-gtest.cmake +17 -0
- data/lib/ckick/plugin_delegate.rb +15 -0
- data/lib/ckick/project.rb +173 -0
- data/lib/ckick/sub_directory.rb +121 -0
- data/lib/ckick/target.rb +81 -0
- data/lib/ckick/version.rb +7 -0
- data/resource/default_cxx_project.json +40 -0
- metadata +129 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/path"
|
6
|
+
|
7
|
+
module CKick
|
8
|
+
|
9
|
+
class IncludePath < Path
|
10
|
+
def raw_flag
|
11
|
+
"-I#{@path}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def cmake
|
15
|
+
%Q{include_directories(#{@path})}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/target"
|
6
|
+
|
7
|
+
module CKick
|
8
|
+
|
9
|
+
class Library < Target
|
10
|
+
def initialize args={}
|
11
|
+
super args
|
12
|
+
|
13
|
+
@shared = args[:shared] || false
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
if @shared
|
18
|
+
return super
|
19
|
+
else
|
20
|
+
return super.without(:shared)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def cmake
|
25
|
+
res = []
|
26
|
+
|
27
|
+
res << "add_library(#{@name}#{@shared ? " SHARED " : " "}#{@source.join(' ')})"
|
28
|
+
|
29
|
+
unless @libs.empty?
|
30
|
+
res << "target_link_libraries(#{@name} #{@libs.join(' ')})"
|
31
|
+
end
|
32
|
+
|
33
|
+
res.join("\n")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
module CKick
|
6
|
+
|
7
|
+
class LibraryLink
|
8
|
+
|
9
|
+
def initialize args={}
|
10
|
+
name = args[:name] || ""
|
11
|
+
raise CKick::IllegalInitializationError, "No name provided to library link" unless name.is_a?(String) && !name.empty?
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash_element
|
16
|
+
@name
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@name
|
21
|
+
end
|
22
|
+
|
23
|
+
def raw_flag
|
24
|
+
"-l#{@name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def cmake
|
28
|
+
@name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/path"
|
6
|
+
|
7
|
+
module CKick
|
8
|
+
|
9
|
+
class LibraryPath < Path
|
10
|
+
def raw_flag
|
11
|
+
"-L#{@path}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def cmake
|
15
|
+
"link_directories(#{@path})"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/ckick/path.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
module CKick
|
6
|
+
|
7
|
+
class Path
|
8
|
+
attr_reader :path
|
9
|
+
|
10
|
+
def initialize args={}
|
11
|
+
raise IllegalInitializationError, "needs :path parameter" unless args.is_a?(Hash) && args[:path].is_a?(String)
|
12
|
+
raise NoSuchDirectoryError, "invalid path #{args[:path]}" unless Dir.exist?(args[:path])
|
13
|
+
|
14
|
+
@path = args[:path]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@path
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash_element
|
22
|
+
@path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
module CKick
|
8
|
+
|
9
|
+
module PathDelegate
|
10
|
+
|
11
|
+
def self.create_directory(dirpath)
|
12
|
+
FileUtils.mkdir_p(dirpath)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.write_file(dirpath, filename, content)
|
16
|
+
raise BadFileContentError, "content does not respond to to_s" unless content.respond_to?(:to_s)
|
17
|
+
filepath = File.join(dirpath, filename)
|
18
|
+
file = File.new(filepath, "w")
|
19
|
+
file << content.to_s
|
20
|
+
file.close
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.touch_file(filepath)
|
24
|
+
FileUtils.touch(filepath)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/ckick/plugin.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
module CKick
|
6
|
+
|
7
|
+
class Plugin
|
8
|
+
def initialize args
|
9
|
+
end
|
10
|
+
|
11
|
+
# Plugin's name, defaults to class name
|
12
|
+
def name
|
13
|
+
self.class.name
|
14
|
+
end
|
15
|
+
|
16
|
+
# Plugin to hash is :name => "class name"
|
17
|
+
def to_hash
|
18
|
+
{name: self.class.name}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Plugin's output to add to main CMakeLists.txt
|
22
|
+
def cmake
|
23
|
+
""
|
24
|
+
end
|
25
|
+
|
26
|
+
# Ran before project's structure creation
|
27
|
+
def run(project)
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Ran after project's structure creation (create_structure)
|
32
|
+
def call(project)
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
# Appends project's includes path before structure creation
|
37
|
+
def include(project)
|
38
|
+
[]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Appends project's libraries path before structure creation
|
42
|
+
def lib(project)
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/plugin"
|
6
|
+
|
7
|
+
class ClangComplete < CKick::Plugin
|
8
|
+
# Creates a .clang_complete file for clang auto completion
|
9
|
+
|
10
|
+
def call(project)
|
11
|
+
def clang_complete project
|
12
|
+
project.dependencies.flags.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
file = File.new(File.join(project.path, ".clang_complete"), 'w')
|
16
|
+
file << clang_complete(project) << "\n"
|
17
|
+
file.close
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/plugin"
|
6
|
+
require "fileutils"
|
7
|
+
|
8
|
+
class GTest < CKick::Plugin
|
9
|
+
LIBS_VARIABLE = "${GTEST_LIBRARIES}"
|
10
|
+
|
11
|
+
def initialize args={}
|
12
|
+
@optional = args[:optional] || false
|
13
|
+
@resource_file = "build-gtest.cmake"
|
14
|
+
end
|
15
|
+
|
16
|
+
def cmake
|
17
|
+
res = ''
|
18
|
+
res << %Q(option(BUILD_TESTS OFF "whether to build tests or not")\n) \
|
19
|
+
<< "if(BUILD_TESTS)\n\t" if @optional
|
20
|
+
|
21
|
+
res << "include(#{@resource_file})"
|
22
|
+
|
23
|
+
res << "\nendif()" if @optional
|
24
|
+
res
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(project)
|
28
|
+
file = File.new(File.join(project.root, @resource_file), 'w')
|
29
|
+
file << File.new(File.join(File.dirname(__FILE__), "resource", @resource_file), 'r').read
|
30
|
+
file.close
|
31
|
+
end
|
32
|
+
|
33
|
+
def include(project)
|
34
|
+
res = []
|
35
|
+
[
|
36
|
+
File.join(project.build_dir, "gtest", "src", "libgtest", "googletest", "include"),
|
37
|
+
File.join(project.build_dir, "gtest", "src", "libgtest", "googlemock", "include")
|
38
|
+
].each do |path|
|
39
|
+
FileUtils.mkdir_p path
|
40
|
+
res << CKick::IncludePath.new(path: path)
|
41
|
+
end
|
42
|
+
res
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
find_package(Threads REQUIRED)
|
2
|
+
include(ExternalProject)
|
3
|
+
|
4
|
+
ExternalProject_Add(
|
5
|
+
libgtest
|
6
|
+
URL https://github.com/google/googletest/archive/release-1.8.0.zip
|
7
|
+
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest
|
8
|
+
INSTALL_COMMAND ""
|
9
|
+
)
|
10
|
+
|
11
|
+
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gtest/src/libgtest/googletest/include")
|
12
|
+
include_directories("${CMAKE_CURRENT_BINARY_DIR}/gtest/src/libgtest/googlemock/include")
|
13
|
+
|
14
|
+
link_directories("${CMAKE_CURRENT_BINARY_DIR}/gtest/src/libgtest-build/googlemock/gtest")
|
15
|
+
link_directories("${CMAKE_CURRENT_BINARY_DIR}/gtest/src/libgtest-build/googlemock")
|
16
|
+
|
17
|
+
set(GTEST_LIBRARIES gtest gtest_main gmock gmock_main pthread)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
module CKick
|
6
|
+
|
7
|
+
module PluginDelegate
|
8
|
+
|
9
|
+
def self.find(plugin)
|
10
|
+
Object.const_get(plugin[:name]).new(plugin[:args] || {})
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require "ckick/nil_class"
|
6
|
+
require "ckick/dependencies"
|
7
|
+
require "ckick/sub_directory"
|
8
|
+
require "ckick/hashable"
|
9
|
+
require "ckick/path_delegate"
|
10
|
+
require "ckick/plugin_delegate"
|
11
|
+
|
12
|
+
module CKick
|
13
|
+
|
14
|
+
class Project
|
15
|
+
include Hashable
|
16
|
+
attr_reader :subdirs, :dependencies, :root, :build_dir
|
17
|
+
|
18
|
+
NAME_MATCH = /^[[A-Z][a-z]_[0-9]]+$/
|
19
|
+
CMAKE_VERSION_MATCH = /^[0-9](\.[0-9]){0,2}$/
|
20
|
+
|
21
|
+
def initialize args
|
22
|
+
name = args[:name] || ""
|
23
|
+
raise IllegalInitializationError, "name must be a non-empty string only containing alphanumeric characters" unless name.is_a?(String) && name.match(NAME_MATCH)
|
24
|
+
|
25
|
+
min_v = args[:cmake_min_version] || '3'
|
26
|
+
raise IllegalInitializationError, "cmake_min_version is non-String" unless min_v.is_a?(String)
|
27
|
+
raise IllegalInitializationError, "cmake_min_version has non working pattern x or x.y or x.y.z" unless min_v.match(CMAKE_VERSION_MATCH)
|
28
|
+
|
29
|
+
root = args[:root] || ""
|
30
|
+
raise IllegalInitializationError, "root directory is non-String" unless root.is_a?(String)
|
31
|
+
raise IllegalInitializationError, "root directory is empty" if root.empty?
|
32
|
+
|
33
|
+
build_dir = args[:build_dir] || ""
|
34
|
+
raise IllegalInitializationError, "build directory is non-String" unless build_dir.is_a?(String)
|
35
|
+
raise IllegalInitializationError, "build directory is empty" if build_dir.empty?
|
36
|
+
|
37
|
+
@name = name
|
38
|
+
@cmake_min_version = min_v
|
39
|
+
@root = root
|
40
|
+
@build_dir = build_dir
|
41
|
+
@dependencies = Dependencies.new(args[:dependencies] || {})
|
42
|
+
|
43
|
+
@plugins = []
|
44
|
+
args[:plugins].each do |plugin|
|
45
|
+
@plugins << PluginDelegate.find(plugin)
|
46
|
+
end
|
47
|
+
|
48
|
+
@subdirs = []
|
49
|
+
args[:subdirs].each do |subdir|
|
50
|
+
@subdirs << SubDirectory.new(subdir)
|
51
|
+
end
|
52
|
+
|
53
|
+
@subdirs_initiated = false
|
54
|
+
init_subdirs
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_name(name)
|
58
|
+
raise BadProjectNameError, "project name must be a non-empty alphanumeric string" unless name.is_a?(String) && name.match(NAME_MATCH)
|
59
|
+
@name = name
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
@name
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_hash
|
67
|
+
to_no_empty_value_hash.without(:subdirs_initiated)
|
68
|
+
end
|
69
|
+
|
70
|
+
def path
|
71
|
+
@root
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_structure
|
75
|
+
raise "SubDirectories have not been initiated" unless @subdirs_initiated
|
76
|
+
|
77
|
+
run_plugins
|
78
|
+
|
79
|
+
PathDelegate.create_directory path
|
80
|
+
PathDelegate.write_file(path, "CMakeLists.txt", cmake)
|
81
|
+
|
82
|
+
@subdirs.each do |subdir|
|
83
|
+
subdir.create_structure
|
84
|
+
end
|
85
|
+
|
86
|
+
call_plugins
|
87
|
+
end
|
88
|
+
|
89
|
+
def register_plugin(plugin=nil, &block)
|
90
|
+
raise ArgumentError, "" unless plugin.is_a?(::CKick::Plugin) || block
|
91
|
+
|
92
|
+
if plugin.is_a?(::CKick::Plugin)
|
93
|
+
@plugins << plugin
|
94
|
+
elsif plugin.nil? && block
|
95
|
+
@plugins << block
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def cmake
|
100
|
+
append_plugin_paths
|
101
|
+
|
102
|
+
res = "project(#{@name})\n" +
|
103
|
+
"cmake_minimum_required(VERSION #{@cmake_min_version})\n\n"
|
104
|
+
|
105
|
+
res << "set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)\n" \
|
106
|
+
"set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)\n" \
|
107
|
+
"set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)\n\n"
|
108
|
+
|
109
|
+
res << @dependencies.cmake << "\n\n"
|
110
|
+
|
111
|
+
res << plugins_cmake << "\n\n" unless @plugins.empty?
|
112
|
+
|
113
|
+
@subdirs.each do |dir|
|
114
|
+
res << "add_subdirectory(#{dir.name})\n" if dir.has_cmake
|
115
|
+
end
|
116
|
+
|
117
|
+
res
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def init_subdirs
|
123
|
+
@subdirs.each do |subdir|
|
124
|
+
subdir.__send__ :set_parent, path
|
125
|
+
end
|
126
|
+
|
127
|
+
@subdirs_initiated = true
|
128
|
+
end
|
129
|
+
|
130
|
+
def append_plugin_paths
|
131
|
+
@plugins.each do |plugin|
|
132
|
+
plugin.include(self).each do |path|
|
133
|
+
@dependencies.add_include path
|
134
|
+
end
|
135
|
+
plugin.lib(self).each do |path|
|
136
|
+
@dependencies.add_lib path
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def run_plugins
|
142
|
+
@plugins.each do |plugin|
|
143
|
+
plugin.run(self) if plugin.respond_to? :run
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def call_plugins
|
148
|
+
@plugins.each do |plugin|
|
149
|
+
plugin.call self
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def plugins_cmake
|
154
|
+
res = "##ckick plugins section##\n"
|
155
|
+
|
156
|
+
def plugin_name(plugin)
|
157
|
+
if plugin.respond_to?(:name)
|
158
|
+
return plugin.name
|
159
|
+
else
|
160
|
+
return "<inline plugin>"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
@plugins.each do |plugin|
|
165
|
+
res << "#ckick plugin: #{plugin_name(plugin)}\n"
|
166
|
+
res << plugin.cmake << "\n" if plugin.respond_to? :cmake
|
167
|
+
end
|
168
|
+
|
169
|
+
res << "##end plugin section##"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|