canoe 0.2.3 → 0.3.1

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.
@@ -0,0 +1,28 @@
1
+ class WorkSpace
2
+ def new
3
+ begin
4
+ Dir.mkdir(@name)
5
+ rescue
6
+ abort_on_err "workspace #{@name} already exsits"
7
+ end
8
+ Dir.mkdir(@src)
9
+ Dir.mkdir(@components)
10
+ Dir.mkdir("#{@workspace}/obj")
11
+ if @mode == :bin
12
+ DefaultFiles.create_main(@src, @source_suffix)
13
+ else
14
+ DefaultFiles.create_lib_header(@src, @name, @header_suffix)
15
+ end
16
+ File.new("#{@workspace}/.canoe", "w")
17
+ DefaultFiles.create_config @workspace, @source_suffix, @header_suffix
18
+ # DefaultFiles.create_emacs_dir_local @workspace
19
+
20
+ Dir.mkdir(@third)
21
+ Dir.mkdir(@target)
22
+ Dir.mkdir(@tests)
23
+ Dir.chdir(@workspace) do
24
+ system "git init"
25
+ end
26
+ puts "workspace #{@workspace.blue} is created"
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ class WorkSpace
2
+ def run(args)
3
+ return if @mode == :lib
4
+ build []
5
+ args = args.join " "
6
+ puts "./target/#{@name} #{args}"
7
+ exec "./target/#{@name} #{args}"
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ class WorkSpace
2
+ public
3
+
4
+ def test(args)
5
+ if args.empty?
6
+ test_all
7
+ return
8
+ end
9
+
10
+ args.each do |arg|
11
+ case arg
12
+ when "all"
13
+ test_all
14
+ else
15
+ test_single arg
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def test_all
23
+ puts "tests all"
24
+ end
25
+
26
+ def test_single(name)
27
+ puts "#{@tests}/bin/test_#{name}"
28
+ # system "./#{@tests}/bin/test_#{name}"
29
+ end
30
+
31
+ ##
32
+ # how to build:
33
+ # each test file tests one or more components, indicated by included headers
34
+ # find corresponding object file in ../obj and link them to test file
35
+ # TODO
36
+ def build_test
37
+ build
38
+ deps = DepAnalyzer.new("./tests").build_to_file(["./src", "./src/components", "./tests", "./tests/common"], "./tests/.canoe.deps")
39
+ puts deps
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ class WorkSpace
2
+ def update
3
+ generate
4
+ end
5
+ end
@@ -0,0 +1,52 @@
1
+ require "fileutils"
2
+ require_relative "../source_files"
3
+ require_relative "../compiler"
4
+ require_relative "../config_reader"
5
+ require_relative "../default_files"
6
+ require_relative "../err"
7
+ require_relative "../dependence"
8
+ require_relative "../coloring"
9
+
10
+ class WorkSpace
11
+ include Err
12
+ attr_reader :name, :cwd, :src_prefix, :components_prefix, :obj_prefix, :source_suffix, :header_suffix, :mode
13
+
14
+ def initialize(name, mode, src_suffix = "cpp", hdr_suffix = "hpp")
15
+ @name = name
16
+ @compiler = Compiler.new "clang++", ["-Isrc/components"], []
17
+ @cwd = Dir.new(Dir.pwd)
18
+ @workspace = "#{Dir.pwd}/#{@name}"
19
+ @src = "#{@workspace}/src"
20
+ @components = "#{@src}/components"
21
+ @obj = "#{@workspace}/obj"
22
+ @third = "#{@workspace}/third-party"
23
+ @target = "#{@workspace}/target"
24
+ @tests = "#{@workspace}/tests"
25
+ @mode = mode
26
+ @deps = ".canoe.deps"
27
+
28
+ @src_prefix = "./src/"
29
+ @components_prefix = "./src/components/"
30
+ @obj_prefix = "./obj/"
31
+
32
+ @source_suffix = src_suffix
33
+ @header_suffix = hdr_suffix
34
+ end
35
+
36
+ def inspect
37
+ puts "name is #{@name}"
38
+ puts "name is #{@workspace}"
39
+ end
40
+ end
41
+
42
+ require_relative "help"
43
+ require_relative "new"
44
+ require_relative "add"
45
+ require_relative "build"
46
+ require_relative "generate"
47
+ require_relative "run"
48
+ require_relative "dep"
49
+ require_relative "clean"
50
+ require_relative "update"
51
+ require_relative "test"
52
+ require_relative "make"
metadata CHANGED
@@ -1,19 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canoe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - XIONG Ziwei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-23 00:00:00.000000000 Z
11
+ date: 2021-02-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- Tired of writing Makefile, CMakeList and even SConstruct? Let Canoe help you wipe them out.
13
+ description: |+
14
+ Canoe offers project management and building facilities to C/C++ projects.
15
+
16
+ If you are tired of writing Makefile, CMakeList and even SConstruct, please let Canoe help you wipe them out.
17
+
15
18
  Similar to Cargo for Rust, Canoe offers commands such as new, build, run, etc. to help you generate a C/C++ project and build it automatically.
16
- No more Makefiles, Canoe would analyze dependencies and build like our old friend make if you follow a few conventions over file names
19
+
20
+ Different from tools like Scons and Blade, Canoe requires users to write NO building scripts, Canoe would analyze dependencies and build like our old friend 'make' if a few conventions over file names are followed.
21
+
17
22
  email: noahxiong@outlook.com
18
23
  executables:
19
24
  - canoe
@@ -23,13 +28,25 @@ files:
23
28
  - bin/canoe
24
29
  - lib/canoe.rb
25
30
  - lib/cmd.rb
31
+ - lib/coloring.rb
26
32
  - lib/compiler.rb
27
33
  - lib/config_reader.rb
28
34
  - lib/default_files.rb
29
35
  - lib/dependence.rb
30
36
  - lib/err.rb
31
37
  - lib/source_files.rb
32
- - lib/workspace.rb
38
+ - lib/workspace/add.rb
39
+ - lib/workspace/build.rb
40
+ - lib/workspace/clean.rb
41
+ - lib/workspace/dep.rb
42
+ - lib/workspace/generate.rb
43
+ - lib/workspace/help.rb
44
+ - lib/workspace/make.rb
45
+ - lib/workspace/new.rb
46
+ - lib/workspace/run.rb
47
+ - lib/workspace/test.rb
48
+ - lib/workspace/update.rb
49
+ - lib/workspace/workspace.rb
33
50
  homepage: https://github.com/Dicridon/canoe
34
51
  licenses:
35
52
  - MIT
@@ -52,5 +69,5 @@ requirements: []
52
69
  rubygems_version: 3.1.2
53
70
  signing_key:
54
71
  specification_version: 4
55
- summary: a C/C++ project management and build tool
72
+ summary: a C/C++ project management and building tool
56
73
  test_files: []
data/lib/workspace.rb DELETED
@@ -1,272 +0,0 @@
1
- require 'fileutils'
2
- require 'open3'
3
- require_relative 'source_files'
4
- require_relative 'compiler'
5
- require_relative 'config_reader'
6
- require_relative 'default_files'
7
- require_relative 'err'
8
- require_relative 'dependence'
9
-
10
- class WorkSpace
11
- include Err
12
- attr_reader :name, :cwd
13
- def self.help
14
- info = <<~INFO
15
- canoe is a C/C++ project manager, inspired by Rust cargo.
16
- usage:
17
- canoe new tada: create a project named 'tada' in current directory
18
-
19
- canoe build: compile current project (execute this command in project directory)
20
-
21
- canoe generate: generate dependency relationship and store it in '.canoe.deps'
22
-
23
- canoe run: compile and execute current project (execute this command in project directory)
24
-
25
- canoe clean: remove all generated object files and binary files
26
-
27
- canoe help: show this help message
28
-
29
- canoe add tada: add a folder named tada under workspace/components,
30
- two files tada.hpp and tada.cpp would be craeted and intialized
31
-
32
- canoe verion: version information
33
-
34
- new project_name [mode] [suffixes]:
35
- create a new project with project_name.
36
- In this project, four directories obj, src, target and third-party will be generated in project directory.
37
- in src, directory 'components' will be generated if [mode] is '--lib', an extra main.cpp will be generated if [mode] is '--bin'
38
-
39
- [mode]: --lib for a library and --bin for executable binaries
40
- [suffixes]: should be in 'source_suffix:header_suffix" format, notice the ':' between two suffixes
41
-
42
- generate:
43
- generate dependence relationship for each file, this may accelarate
44
- `canoe buid` command. It's recommanded to execute this command everytime
45
- headers are added or removed from any file.
46
-
47
- build [options]:
48
- build current project, arguments in [options] will be passed to C++ compiler
49
-
50
- run [options]:
51
- build current project with no specific compilation flags, and run this project, passing [options] as command line arguments to the binary
52
-
53
- clean:
54
- remove all generated object files and binary files
55
-
56
- help:
57
- show this help message
58
-
59
- verion:
60
- display version information
61
-
62
- dep:
63
- display file dependencies in a better readable way
64
-
65
- @author: written by XIONG Ziwei, ICT, CAS
66
- @contact: noahxiong@outlook.com
67
- INFO
68
- puts info
69
- end
70
-
71
-
72
- def initialize(name, mode, src_suffix='cpp', hdr_suffix='hpp')
73
- @name = name
74
- @compiler = Compiler.new 'clang++', '-Isrc/components'
75
- @cwd = Dir.new(Dir.pwd)
76
- @workspace = "#{Dir.pwd}/#{@name}"
77
- @src = "#{@workspace}/src"
78
- @components = "#{@src}/components"
79
- @obj = "#{@workspace}/obj"
80
- @third = "#{@workspace}/third-party"
81
- @target = "#{@workspace}/target"
82
- @mode = mode
83
- @deps = '.canoe.deps'
84
-
85
- @src_prefix = './src/'
86
- @components_prefix = './src/components/'
87
- @obj_prefix = './obj/'
88
-
89
- @source_suffix = src_suffix
90
- @header_suffix = hdr_suffix
91
- end
92
-
93
- def new
94
- Dir.mkdir(@name)
95
- Dir.mkdir(@src)
96
- Dir.mkdir(@components)
97
- Dir.mkdir("#{@workspace}/obj")
98
- DefaultFiles.create_main(@src, @source_suffix) if @mode == :bin
99
- File.new("#{@workspace}/.canoe", "w")
100
- DefaultFiles.create_config @workspace, @source_suffix, @header_suffix
101
- DefaultFiles.create_emacs_dir_local @workspace
102
-
103
- Dir.mkdir(@third)
104
- Dir.mkdir(@target)
105
- puts "workspace #{@workspace} is created"
106
- end
107
-
108
- # args are commandline parameters passed to `canoe build`
109
- def build(args)
110
- deps = File.exist?(@deps) ?
111
- DepAnalyzer.read_from(@deps) :
112
- DepAnalyzer.new('./src').build_to_file(['./src', './src/components'], @deps)
113
- target = "./target/#{@name}"
114
- build_time = File.exist?(target) ? File.mtime(target) : Time.new(0)
115
- files = DepAnalyzer.compiling_filter(deps, build_time, @source_suffix, @header_suffix)
116
-
117
- if files.empty?
118
- puts "nothing to do, all up to date"
119
- return
120
- end
121
-
122
- self.send "build_#{@mode.to_s}", files, args
123
- end
124
-
125
- def generate
126
- DepAnalyzer.new('./src', @source_suffix, @header_suffix)
127
- .build_to_file ['./src', './src/components'], @deps
128
- end
129
-
130
- def update
131
- generate
132
- end
133
-
134
- def clean
135
- self.send "clean_#{@mode.to_s}"
136
- end
137
-
138
- def run(args)
139
- build []
140
- args = args.join " "
141
- puts "./target/#{@name} #{args}"
142
- exec "./target/#{@name} #{args}"
143
- end
144
-
145
- def add(args)
146
- args.each do |i|
147
- dir = @components
148
- filenames = i.split("/")
149
- prefix = []
150
- filenames.each do |filename|
151
- dir += "/#{filename}"
152
- prefix << filename
153
- unless Dir.exist? dir
154
- FileUtils.mkdir dir
155
- Dir.chdir(dir) do
156
- puts "created " + Dir.pwd
157
- create_working_files prefix.join('__'), filename
158
- end
159
- end
160
- end
161
- end
162
- end
163
-
164
- def dep
165
- deps = DepAnalyzer.read_from(@deps) if File.exist?(@deps)
166
- deps.each do |k, v|
167
- unless v.empty?
168
- puts "#{k} depends on: "
169
- v.each {|f| puts " #{f}"}
170
- puts ""
171
- end
172
- end
173
- end
174
-
175
- private
176
- def create_working_files(prefix, filename)
177
- DefaultFiles.create_cpp filename, @source_suffix, @header_suffix
178
- DefaultFiles.create_hpp @name, prefix, filename, @header_suffix
179
- end
180
-
181
- def build_compiler_from_config(args)
182
- Dir.chdir(@workspace) do
183
- flags = ConfigReader.extract_flags "config.json"
184
- compiler_name = flags['compiler'] ? flags['compiler'] : "clang++"
185
- abort_on_err "compiler #{compiler_name} not found" unless File.exists?("/usr/bin/#{compiler_name}")
186
- compiler_flags = ['-Isrc/components'] + args
187
-
188
- if opts = flags['flags']
189
- opts.each do |k, v|
190
- case v
191
- when String
192
- compiler_flags << v
193
- when Array
194
- v.each do |o|
195
- compiler_flags << o
196
- end
197
- else
198
- abort_on_err "unknown options in config.json, #{v}"
199
- end
200
- end
201
- end
202
-
203
- @compiler = Compiler.new compiler_name, compiler_flags
204
- end
205
- end
206
-
207
- def compile(f, o)
208
- @compiler.compile f, o
209
- end
210
-
211
- def link(odir, objs)
212
- status = system "#{@compiler} -o #{odir}/#{@name} #{objs.join(" ")}"
213
- unless status
214
- puts "compilation failed"
215
- return
216
- end
217
-
218
- @compiler.link "#{odir}/#{@name}", objs
219
- end
220
-
221
- def build_bin(files, args)
222
- build_compiler_from_config args
223
- comps = files.select {|f| f.start_with? @components_prefix}
224
- srcs = files - comps
225
-
226
- srcs.each do |f|
227
- puts "compiling #{f}"
228
- fname = f.split("/")[-1]
229
- o = @obj_prefix + fname.delete_suffix(File.extname(fname)) + '.o'
230
- compile f, o
231
- end
232
-
233
- comps.each do |f|
234
- puts "compiling #{f}"
235
- o = @obj_prefix + f.delete_suffix(File.extname(f))[@components_prefix.length..]
236
- .gsub('/', '_') + '.o'
237
- compile f, o
238
- end
239
-
240
- link('./target', Dir.glob("obj/*.o")) unless files.empty?
241
- end
242
-
243
- def build_lib
244
- puts "build a lib"
245
- end
246
-
247
- def clean_obj
248
- puts "rm -f ./obj/*.o"
249
- system "rm -f ./obj/*.o"
250
- end
251
-
252
- def clean_target
253
- puts "rm -f ./target/*"
254
- system "rm -f ./target/*"
255
- end
256
-
257
- def clean_bin
258
- clean_obj
259
- clean_target
260
- end
261
-
262
- def clean_lib
263
- clean_obj
264
- clean_target
265
- end
266
-
267
- public
268
- def inspect
269
- puts "name is #{@name}"
270
- puts "name is #{@workspace}"
271
- end
272
- end