Skip to content

Commit 1a91ea8

Browse files
committed
Add script to compile a C++ example
1 parent 852ffe5 commit 1a91ea8

File tree

1 file changed

+299
-0
lines changed

1 file changed

+299
-0
lines changed

tools/scripts/compile_cpp_example

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
#!/usr/bin/env bash
2+
#
3+
# @license Apache-2.0
4+
#
5+
# Copyright (c) 2018 The Stdlib Authors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# Script for compiling a C++ example.
20+
#
21+
# Usage: compile_cpp_example <filepath>
22+
#
23+
# Arguments:
24+
#
25+
# filepath Example file path.
26+
#
27+
#
28+
# Environment Variables:
29+
#
30+
# OS Host operating system. Default: `linux`.
31+
# NODE Command for running Node.js. Default: `node`.
32+
# NODE_PATH Path for resolving node modules.
33+
# CXX_COMPILER C++ compiler. Default: `g++`.
34+
# INCLUDE Includes (e.g., `-I /foo/bar -I /a/b`).
35+
# SOURCE_FILES Source file list.
36+
# LIBRARIES Linked libraries (e.g., `-lopenblas -lpthreads`).
37+
# LIBPATH Library paths (e.g., `-L /foo/bar -L /a/b`).
38+
#
39+
40+
41+
# VARIABLES #
42+
43+
# Set the example file path:
44+
file_path="$1"
45+
46+
# Define the host operating system:
47+
os="${OS}"
48+
if [[ "${os}" = "Darwin" ]]; then
49+
os='mac'
50+
elif [[ "${os}" = "WINNT" ]]; then
51+
os='win'
52+
else
53+
os='linux'
54+
fi
55+
56+
# Define the command for running Node.js:
57+
node_cmd="${NODE}"
58+
if [[ -z "${node_cmd}" ]]; then
59+
node_cmd='node'
60+
fi
61+
62+
# Define the node path:
63+
node_path="${NODE_PATH}"
64+
65+
# Define the path to a C++ compiler:
66+
cxx_compiler="${CXX_COMPILER}"
67+
if [[ -z "${cxx_compiler}" ]]; then
68+
cxx_compiler='g++'
69+
fi
70+
71+
# Define a list of `include` directories (e.g., `-I /foo/bar -I /beep/boop/include`):
72+
include="${INCLUDE}"
73+
74+
# Define a list of source files:
75+
source_files="${SOURCE_FILES}"
76+
77+
# Define a list of libraries (e.g., `-lopenblas -lpthreads`):
78+
libraries="${LIBRARIES}"
79+
80+
# Define a list of library paths (e.g., `-L /foo/bar -L /beep/boop`):
81+
libpath="${LIBPATH}"
82+
83+
84+
# FUNCTIONS #
85+
86+
# Defines an error handler.
87+
#
88+
# $1 - error status
89+
on_error() {
90+
echo 'ERROR: An error was encountered during execution.' >&2
91+
cleanup
92+
exit "$1"
93+
}
94+
95+
# Runs clean-up tasks.
96+
cleanup() {
97+
echo '' >&2
98+
}
99+
100+
# Prints a success message.
101+
print_success() {
102+
echo 'Success!' >&2
103+
}
104+
105+
# Prints usage information.
106+
usage() {
107+
echo '' >&2
108+
echo 'Usage: compile_cpp_example <filepath>' >&2
109+
echo '' >&2
110+
}
111+
112+
# Resolves a package path.
113+
#
114+
# $1 - source directory
115+
resolve_pkg_path() {
116+
local pkg_path
117+
local script
118+
119+
# Generate the script for resolving a package path:
120+
script='"'"var resolve = require('@stdlib/fs/resolve-parent-path').sync; var dirname = require('@stdlib/utils/dirname'); var opts = {'dir':'$1'}; var path = resolve('package.json', opts); console.log(dirname(path));"'"'
121+
122+
# Resolve package path:
123+
pkg_path=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
124+
125+
echo "${pkg_path}"
126+
}
127+
128+
# Resolves a package `manifest.json`.
129+
#
130+
# $1 - package path
131+
resolve_pkg_manifest() {
132+
if [[ -e "$1/manifest.json" ]]; then
133+
return 0
134+
fi
135+
return 1
136+
}
137+
138+
# Resolves `include` directories.
139+
#
140+
# $1 - package directory
141+
resolve_includes() {
142+
local includes
143+
local script
144+
local opts
145+
146+
opts='{}'
147+
148+
# Generate the script for resolving `include` directories:
149+
script='"'"var path = require('path'); var arr = require('@stdlib/tools/library-manifest')(path.join('$1','manifest.json'),${opts},{'basedir':'$1','paths':'posix'}).include; var str = ''; for (var i = 0; i < arr.length; i++){var p = path.resolve('$1', arr[i]); str += '-I '+p+' ';}; console.log(str.substring(0, str.length-1));"'"'
150+
151+
# Resolve `include` directories:
152+
includes=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
153+
154+
echo "${includes}"
155+
}
156+
157+
# Resolves source files.
158+
#
159+
# $1 - package directory
160+
resolve_source_files() {
161+
local source_files
162+
local script
163+
local opts
164+
165+
opts='{}'
166+
167+
# Generate the script for resolving source files:
168+
script='"'"var path = require('path'); var arr = require('@stdlib/tools/library-manifest')(path.join('$1','manifest.json'),${opts},{'basedir':'$1','paths':'posix'}).src; var str = ''; for (var i = 0; i < arr.length; i++){var p = path.resolve('$1', arr[i]); str += p+' ';}; console.log(str.substring(0, str.length-1));"'"'
169+
170+
# Resolve files:
171+
source_files=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
172+
173+
echo "${source_files}"
174+
}
175+
176+
# Resolves libraries.
177+
#
178+
# $1 - package directory
179+
resolve_libraries() {
180+
local libraries
181+
local script
182+
local opts
183+
184+
opts='{}'
185+
186+
# Generate the script for resolving libraries:
187+
script='"'"var path = require('path'); var arr = require('@stdlib/tools/library-manifest')(path.join('$1','manifest.json'),${opts},{'basedir':'$1','paths':'posix'}).libraries; var str = ''; for (var i = 0; i < arr.length; i++){str += arr[i]+' ';}; console.log(str.substring(0, str.length-1));"'"'
188+
189+
# Resolve libraries:
190+
libraries=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
191+
192+
echo "${libraries}"
193+
}
194+
195+
# Resolves library paths.
196+
#
197+
# $1 - package directory
198+
resolve_libpaths() {
199+
local libpath
200+
local script
201+
local opts
202+
203+
opts='{}'
204+
205+
# Generate the script for resolving library paths:
206+
script='"'"var path = require('path'); var arr = require('@stdlib/tools/library-manifest')(path.join('$1','manifest.json'),${opts},{'basedir':'$1','paths':'posix'}).libpath; var str = ''; for (var i = 0; i < arr.length; i++){var p = path.resolve('$1', arr[i]); str += '-L '+p+' ';}; console.log(str.substring(0, str.length-1));"'"'
207+
208+
# Resolve library paths:
209+
libpath=$(eval NODE_PATH="${node_path}" "${node_cmd}" -e "${script}")
210+
211+
echo "${libpath}"
212+
}
213+
214+
# Compiles example.
215+
#
216+
# $1 - source directory
217+
compile() {
218+
cd "$1" && CXX_COMPILER="${cxx_compiler}" INCLUDE="${include}" SOURCE_FILES="${source_files}" LIBRARIES="${libraries}" LIBPATH="${libpath}" make 2>&1
219+
if [[ "$?" -ne 0 ]]; then
220+
echo 'Error when attempting to compile example.' >&2
221+
return 1
222+
fi
223+
echo 'Successfully compiled example.' >&2
224+
return 0
225+
}
226+
227+
228+
# MAIN #
229+
230+
# Main execution sequence.
231+
main() {
232+
local pkg_path
233+
local manifest
234+
local src_dir
235+
236+
echo 'Resolving package path...' >&2
237+
pkg_path=$(resolve_pkg_path "${src_dir}")
238+
if [[ "$?" -ne 0 ]]; then
239+
on_error 1
240+
fi
241+
echo "Package path: ${pkg_path}" >&2
242+
243+
echo 'Resolving package manifest...' >&2
244+
manifest=$(resolve_pkg_manifest "${pkg_path}")
245+
if [[ "$?" -eq 0 ]]; then
246+
echo 'Successfully resolved package manifest.' >&2
247+
if [[ -z "${include}" ]]; then
248+
echo 'Resolving include directories...' >&2
249+
include=$(resolve_includes "${pkg_path}")
250+
if [[ "$?" -ne 0 ]]; then
251+
on_error 1
252+
fi
253+
fi
254+
if [[ -z "${source_files}" ]]; then
255+
echo 'Resolving source files...' >&2
256+
source_files=$(resolve_source_files "${pkg_path}")
257+
if [[ "$?" -ne 0 ]]; then
258+
on_error 1
259+
fi
260+
fi
261+
if [[ -z "${libraries}" ]]; then
262+
echo 'Resolving libraries...' >&2
263+
libraries=$(resolve_libraries "${pkg_path}")
264+
if [[ "$?" -ne 0 ]]; then
265+
on_error 1
266+
fi
267+
fi
268+
if [[ -z "${libpath}" ]]; then
269+
echo 'Resolving library paths...' >&2
270+
libpath=$(resolve_libpaths "${pkg_path}")
271+
if [[ "$?" -ne 0 ]]; then
272+
on_error 1
273+
fi
274+
fi
275+
else
276+
echo 'Unable to resolve package manifest.' >&2
277+
fi
278+
echo 'Compiling example...' >&2
279+
src_dir=$(dirname "${file_path}")
280+
compile "${src_dir}"
281+
if [[ "$?" -ne 0 ]]; then
282+
on_error 1
283+
fi
284+
print_success
285+
cleanup
286+
exit 0
287+
}
288+
289+
# Handle arguments...
290+
if [[ "$#" -eq 0 ]]; then
291+
usage
292+
exit 0
293+
elif [[ "$#" -gt 1 ]]; then
294+
echo 'ERROR: unrecognized arguments. Must provide a file path.' >&2
295+
exit 1
296+
fi
297+
298+
# Run main:
299+
main

0 commit comments

Comments
 (0)