Statistics
| Branch: | Tag: | Revision:

amiro-os / tools / ide / QtCreator / QtCreatorSetup.sh @ e189c0a6

History | View | Annotate | Download (26.805 KB)

1
################################################################################
2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3
# (AMiRo) platform.                                                            #
4
# Copyright (C) 2016..2020  Thomas Schöpping et al.                            #
5
#                                                                              #
6
# This program is free software: you can redistribute it and/or modify         #
7
# it under the terms of the GNU General Public License as published by         #
8
# the Free Software Foundation, either version 3 of the License, or            #
9
# (at your option) any later version.                                          #
10
#                                                                              #
11
# This program is distributed in the hope that it will be useful,              #
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
14
# GNU General Public License for more details.                                 #
15
#                                                                              #
16
# You should have received a copy of the GNU General Public License            #
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
18
#                                                                              #
19
# This research/work was supported by the Cluster of Excellence Cognitive      #
20
# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
21
# funded by the German Research Foundation (DFG).                              #
22
################################################################################
23

    
24
#!/bin/bash
25

    
26
# load library
27
source "$(dirname ${BASH_SOURCE[0]})/../../bash/setuplib.sh"
28

    
29
### print welcome text #########################################################
30
# Prints a welcome message to standard out.
31
#
32
# usage:      printWelcomeText
33
# arguments:  n/a
34
# return:     n/a
35
#
36
function printWelcomeText {
37
  printf "######################################################################\n"
38
  printf "#                                                                    #\n"
39
  printf "#                  Welcome to the QtCreator setup!                   #\n"
40
  printf "#                                                                    #\n"
41
  printf "######################################################################\n"
42
  printf "#                                                                    #\n"
43
  printf "# Copyright (c) 2016..2020  Thomas Schöpping                         #\n"
44
  printf "#                                                                    #\n"
45
  printf "# This is free software; see the source for copying conditions.      #\n"
46
  printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
47
  printf "# A PARTICULAR PURPOSE. The development of this software was         #\n"
48
  printf "# supported by the Excellence Cluster EXC 227 Cognitive Interaction  #\n"
49
  printf "# Technology. The Excellence Cluster EXC 227 is a grant of the       #\n"
50
  printf "# Deutsche Forschungsgemeinschaft (DFG) in the context of the German #\n"
51
  printf "# Excellence Initiative.                                             #\n"
52
  printf "#                                                                    #\n"
53
  printf "######################################################################\n"
54
}
55

    
56
### print help #################################################################
57
# Prints a help text to standard out.
58
#
59
# usage:      printHelp
60
# arguments:  n/a
61
# return:     n/a
62
#
63
function printHelp {
64
  printInfo "printing help text\n"
65
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-m|--module=<module>] [-a|--all] [-c|--clean] [-w|--wipe] [-q|--quit] [--log=<file>]\n"
66
  printf "\n"
67
  printf "options:  -h, --help\n"
68
  printf "              Print this help text.\n"
69
  printf "          -m, --module <module>\n"
70
  printf "              Create project for a single module.\n"
71
  printf "          -a, --all\n"
72
  printf "              Create projects for all modules.\n"
73
  printf "          -c, --clean\n"
74
  printf "              Delete project files.\n"
75
  printf "          -w, --wipe\n"
76
  printf "              Delete project and .user files.\n"
77
  printf "          -q, --quit\n"
78
  printf "              Quit the script.\n"
79
  printf "          --log=<file>\n"
80
  printf "              Specify a log file.\n"
81
}
82

    
83
### read directory where to create/delete projects #############################
84
# Read the directory where to create/delete project files from user.
85
#
86
# usage:      getProjectDir <pathvar>
87
# arguments:  <pathvar>
88
#                 Variable to store the selected path to.
89
# return:     n/a
90
#
91
function getProjectDir {
92
  printLog "reading path for project files from user...\n"
93
  local amiroosdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../)
94
  local input=""
95
  read -p "Path where to create/delete project files: " -i $amiroosdir -e input
96
  printLog "user selected path $(realpath $input)\n"
97
  eval $1="$(realpath $input)"
98
}
99

    
100
### retrieves the ARM-NONE-EABI-GCC include directory ##########################
101
# Retrieves the include directory of the currently set arm-none-eabi-gcc.
102
#
103
# usage:      retrieveGccIncludeDir <path>
104
# arguments:  <path>
105
#                 Variable to store the path to.
106
# return:    0
107
#                 No error or warning occurred.
108
#            -1
109
#                 Error: Command 'arm-none-eabi-gcc' not found.
110
#            -2
111
#                 Error: include directory could not be resolved.
112
#
113
function retrieveGccIncludeDir {
114
  # retrieve binary path or link
115
  local binpath=$(which arm-none-eabi-gcc)
116
  local gccincpath=""
117
  if [ -z "$binpath" ]; then
118
    printError "command 'arm-none-eabi-gcc' not found\n"
119
    return -1
120
  else 
121

    
122
    # traverse any links
123
    while [ -L "$binpath" ]; do
124
      binpath=$(realpath $(dirname $binpath)/$(readlink $binpath))
125
    done
126
    printInfo "gcc-arm-none-eabi detected: $binpath\n"
127

    
128
    # return include path
129
    gccincpath=$(realpath $(dirname ${binpath})/../arm-none-eabi/include/)
130
    if [ ! -d "$gccincpath" ]; then
131
      printWarning "$gccincpath does not exist\n"
132
      return -2
133
    else
134
      eval $1="$gccincpath"
135
      return 0
136
    fi
137
  fi
138
}
139

    
140
### detect available modules ###################################################
141
# Detect all avalable modules supported by AMiRo-OS.
142
#
143
# usage:      detectModules <modulearray>
144
# arguments:  <modulearray>
145
#                 Array variable to store all detected modules to.
146
# return:     n/a
147
#
148
function detectModules {
149
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
150
  local modules_detected=()
151

    
152
  # detect all available modules (via directories)
153
  for dir in $(ls -d ${modulesdir}/*/); do
154
    modules_detected[${#modules_detected[@]}]=$(basename $dir)
155
  done
156

    
157
  # set the output variable
158
  eval "$1=(${modules_detected[*]})"
159
}
160

    
161
### create project files for a single module ###################################
162
# Create project files for a single module.
163
#
164
# usage:      createModuleProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
165
# arguments:  <modules>
166
#                 Array containing all modules available.
167
#             -m, --module <module>
168
#                 Name (folder name) of the module for which project files shall be generated.
169
#             -p, --path <path>
170
#                 Path where to create the project files.
171
#             --gcc=<path>
172
#                 Path to the GCC include directory.
173
#             -o, --out <var>
174
#                 Variable to store the path to.
175
#             --gccout=<var>
176
#                 Variable to store the path to the GCC include directory to.
177
#                 If this optional arguments is absent, ths function will ask for user input.
178
# return:     0
179
#                 No error or warning occurred.
180
#             1
181
#                 Aborted by user.
182
#             -1
183
#                 No modules available.
184
#             -2
185
#                 The specified <module> could not be found.
186
#             -3
187
#                 Parsing the project for the specified module failed.
188
#             -4
189
#                 Missing dependencies.
190
#
191
function createModuleProject {
192
  local userdir=$(pwd)
193
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
194
  local modules=("${!1}")
195
  local module=""
196
  local moduleidx=""
197
  local projectdir=""
198
  local gccincludedir=""
199
  local outvar=""
200
  local gccoutvar=""
201

    
202
  # check dependencies
203
  checkCommands make
204
  if [ $? -ne 0 ]; then
205
    printError "Missing dependencies detected.\n"
206
    return -4
207
  fi
208

    
209
  # parse arguments
210
  local otherargs=()
211
  while [ $# -gt 0 ]; do
212
    if ( parseIsOption $1 ); then
213
      case "$1" in
214
        -m=*|--module=*)
215
          module="${1#*=}"; shift 1;;
216
        -m|--module)
217
          module="$2"; shift 2;;
218
        -p=*|--path=*)
219
          projectdir=$(realpath "${1#*=}"); shift 1;;
220
        -p|--path)
221
          projectdir=$(realpath "$2"); shift 2;;
222
        --gcc=*)
223
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
224
        --gcc)
225
          gccincludedir=$(realpath "$2"); shift 2;;
226
        -o=*|--out=*)
227
          outvar=${1#*=}; shift 1;;
228
        -o|--out)
229
          outvar=$2; shift 2;;
230
        --gccout=*)
231
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
232
        --gccout)
233
          gccoutvar=$(realpath "$2"); shift 2;;
234
        *)
235
          printError "invalid option: $1\n"; shift 1;;
236
      esac
237
    else
238
      otherargs+=("$1")
239
      shift 1
240
    fi
241
  done
242

    
243
  # sanity check for the modules variable
244
  if [ -z "${modules[*]}" ]; then
245
    printError "no modules available\n"
246
    return -1
247
  fi
248

    
249
  # select module
250
  if [ -z $module ]; then
251
    # list all available modules
252
    printInfo "choose a module or type 'A' to abort:\n"
253
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
254
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
255
    done
256
    # read user input
257
    printLog "read user selection\n"
258
    local userinput=""
259
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; do
260
      read -p "your selection: " -e userinput
261
      printLog "user selection: $userinput\n"
262
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
263
        printWarning "Please enter an integer between 1 and ${#modules[@]} or 'A' to abort.\n"
264
      fi
265
    done
266
    if [[ "$userinput" =~ ^[Aa]$ ]]; then
267
      printWarning "aborted by user\n"
268
      return 1
269
    fi
270
    # store selection
271
    moduleidx=$(($userinput - 1))
272
    module="${modules[$moduleidx]}"
273
    printf "\n"
274
  else
275
    # search all modules for the selected one
276
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
277
      if [ "${modules[$idx]}" = "$module" ]; then
278
        moduleidx=$idx
279
        break
280
      fi
281
    done
282
    # error if the module could not be found
283
    if [ -z $moduleidx ]; then
284
      printError "module ($module) not available\n"
285
      return -2
286
    fi
287
  fi
288

    
289
  # read absolute project directory if required
290
  if [ -z "$projectdir" ]; then
291
    getProjectDir projectdir
292
    printf "\n"
293
  fi
294

    
295
  # check for existing project files
296
  local projectfiles=($(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$"))
297
  if [ ${#projectfiles[@]} != 0 ]; then
298
    printWarning "The following files will be overwritten:\n"
299
    for pfile in ${projectfiles[@]}; do
300
      printWarning "\t$(basename $pfile)\n"
301
    done
302
    local userinput=""
303
    printInfo "Continue and overwrite? [y/n]\n"
304
    readUserInput "YyNn" userinput
305
    case "$userinput" in
306
      Y|y)
307
        ;;
308
      N|n)
309
        printWarning "Project generation for ${module} module aborted by user\n"
310
        return 1
311
        ;;
312
      *)
313
        printError "unexpected input: ${userinput}\n"; return -999;;
314
    esac
315
    printf "\n"
316
  fi
317

    
318
  # print message
319
  printInfo "generating QtCreator project files for the $module module...\n"
320

    
321
  # retrieve absolute GCC include path
322
  if [ -z "$gccincludedir" ]; then
323
    retrieveGccIncludeDir gccincludedir
324
  fi
325

    
326
  # change to project directory
327
  cd "$projectdir"
328

    
329
  # run make, but only run the GCC preprocessor and produce no binaries
330
  local sourcefiles=()
331
  local sourcefile=""
332
  local parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
333
  local makedir=""
334
  local makedirs=()
335
  local quotes="\'\"\´\`\„\“"
336
  # capture all output from make and GCC and append the return value of make as last line
337
  printInfo "processing project (this may take a while)...\n"
338
  local rawout=$(make --directory ${modulesdir}/${module} --always-make USE_OPT="-v -E -H" USE_VERBOSE_COMPILE="no" OUTFILES="" 2>&1 && echo $?)
339
  # check whether the make call was successfull
340
  if [[ $(echo "${rawout}" | tail -n 1) != "0" ]]; then
341
    printError "executing 'make' in module directory failed\n"
342
    cd "$userdir"
343
    return -3
344
  else
345
    # cleanup
346
    make --directory ${modulesdir}/${module} clean &>/dev/null
347
  fi
348
  # extract file names from raw output
349
  IFS=$'\n'; rawout=($rawout); unset IFS
350
  for line in "${rawout[@]}"; do
351
    case $parse_state in
352
      WAIT_FOR_INCLUDE_COMPILE_MAKE)
353
        # lines stating include files look like:
354
        # ... <../relative/path/to/file>
355
        if [[ "$line" =~ ^\.+[[:blank:]].+\..+$ ]]; then
356
          sourcefile=${line##* }
357
          if [[ ! "$sourcefile" =~ ^/ ]]; then
358
            sourcefile=$(realpath ${makedirs[-1]}/${sourcefile})
359
          fi
360
          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
361
        # whenever the next source file is processed, a message appears like:
362
        # Compiling <filename>
363
        elif [[ "$line" =~ ^Compiling[[:blank:]](.+\..+)$ ]]; then
364
          printf "."
365
          sourcefile=${BASH_REMATCH[1]}
366
          parse_state="WAIT_FOR_COMPILERCALL"
367
        # if make is called again in another directory or a nested make call leaves the directory, a message appears like:
368
        # make[1]: Entering directory 'directory'
369
        # make[999]: Verzeichnis „directory“ wird verlassen
370
        elif [[ "$line" =~ ^make(\[[0-9]+\])?:([[:alnum:]]|[[:blank:]])*[$quotes].*[$quotes]([[:alnum:]]|[[:blank:]])*$ ]]; then
371
          # extract directory path
372
          makedir=$(echo ${line} | grep -oE "[${quotes}].*[${quotes}]" | grep -oE "[^${quotes}].*[^${quotes}]")
373
          # if the makedirs stack is empty or the directory does not mathc the last entry
374
          if [ ${#makedirs[@]} == 0 ] || [ "${makedir}" != "${makedirs[-1]}" ]; then
375
            # push the directory to the stack
376
            makedirs+=(${makedir})
377
          else
378
            # pop the directory from the stack
379
            unset makedirs[-1]
380
          fi
381
        fi;;
382
      WAIT_FOR_COMPILERCALL)
383
        # wait for the actual call of the compiler to retrieve the full path to the source file
384
        if [[ "$line" == *${sourcefile}* ]]; then
385
          line="${line%%${sourcefile}*}${sourcefile}"
386
          line="${line##* }"
387
          if [[ "$line" =~ ^/ ]]; then
388
            # aboslute path
389
            sourcefile=$line
390
          else
391
            # relative path
392
            sourcefile=$(realpath ${makedirs[-1]}/${line##* })
393
          fi
394
          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
395
          parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
396
        fi;;
397
    esac
398
  done
399
  unset rawout
400
  printf "\n"
401
  # sort and remove duplicates
402
  IFS=$'\n'; sourcefiles=($(sort --unique <<< "${sourcefiles[*]}")); unset IFS
403

    
404
  # extract include paths
405
  local includes=()
406
  for source in ${sourcefiles[*]}; do
407
    includes[${#includes[@]}]="$(dirname ${source})"
408
  done
409
  # sort and remove duplicates
410
  IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
411

    
412
  # generate the .incldues file, containing all include paths
413
  echo "" > ${projectdir}/${module}.includes
414
  for inc in ${includes[*]}; do
415
    echo "$inc" >> ${projectdir}/${module}.includes
416
  done
417
  # generate the .files file, containing all source files
418
  echo "" > ${projectdir}/${module}.files
419
  for source in ${sourcefiles[*]}; do
420
    # skip GCC files
421
    if [[ ! "$source" =~ .*/gcc.* ]]; then
422
      echo "$source" >> ${projectdir}/${module}.files
423
    fi
424
  done
425
  # generate a default project configuration file if it doesn't exist yet
426
  if [ ! -f ${projectdir}/${module}.config ]; then
427
    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/${module}.config
428
    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/${module}.config
429
  fi
430
  # generate a default .creator file if it doesn't exist yet
431
  if [ ! -f ${projectdir}/${module}.creator ]; then
432
    echo "[general]" > ${projectdir}/${module}.creator
433
  fi
434

    
435
  # go back to user directory
436
  cd $userdir
437

    
438
  # fill the output variables
439
  if [ ! -z "$outvar" ]; then
440
    eval $outvar="$projectdir"
441
  fi
442
  if [ ! -z "$gccoutvar" ]; then
443
    eval $gccoutvar="$gccincludedir"
444
  fi
445

    
446
  return 0
447
}
448

    
449
### create project files for all modules #######################################
450
# Create project files for all modules.
451
#
452
# usage:      createAllProjects <modules> [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
453
# arguments:  <modules>
454
#                 Array containing all modules available.
455
#             -p, --path <path>
456
#                 Path where to create the project files.
457
#             --gcc=<path>
458
#                 Path to the GCC include directory.
459
#             -o, --out <var>
460
#                 Variable to store the path to.
461
#             --gccout=<var>
462
#                 Variable to store the path to the GCC include directory to.
463
#                 If this optional arguments is absent, ths function will ask for user input.
464
# return:     0
465
#                 No error or warning occurred.
466
#             1
467
#                 Aborted by user.
468
#             -1
469
#                 No modules available.
470
#
471
function createAllProjects {
472
  local modules=("${!1}")
473
  local projectsdir=""
474
  local gccincludedir=""
475
  local outvar=""
476
  local gccoutvar=""
477

    
478
  # parse arguments
479
  local otherargs=()
480
  while [ $# -gt 0 ]; do
481
    if ( parseIsOption $1 ); then
482
      case "$1" in
483
        -p=*|--path=*)
484
          projectsdir=$(realpath "${1#*=}"); shift 1;;
485
        -p|--path)
486
          projectsdir=$(realpath "$2"); shift 2;;
487
        --gcc=*)
488
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
489
        --gcc)
490
          gccincludedir=$(realpath "$2"); shift 2;;
491
        -o=*|--out=*)
492
          outvar=${1#*=}; shift 1;;
493
        -o|--out)
494
          outvar=$2; shift 2;;
495
        --gccout=*)
496
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
497
        --gccout)
498
          gccoutvar=$(realpath "$2"); shift 2;;
499
        *)
500
          printError "invalid option: $1\n"; shift 1;;
501
      esac
502
    else
503
      otherargs+=("$1")
504
      shift 1
505
    fi
506
  done
507

    
508
  # sanity check for the modules variable
509
  if [ -z "${modules[*]}" ]; then
510
    printError "no modules available\n"
511
    return -1
512
  fi
513

    
514
  # read absolute project directory if required
515
  if [ -z "$projectsdir" ]; then
516
    getProjectDir projectsdir
517
  fi
518

    
519
  # check for existing project files
520
  local projectfiles=()
521
  for module in ${modules[@]}; do
522
    projectfiles+=($(find ${projectsdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$"))
523
  done
524
  if [ ${#projectfiles[@]} != 0 ]; then
525
    printWarning "The following files will be removed:\n"
526
    for pfile in ${projectfiles[@]}; do
527
      printWarning "\t$(basename $pfile)\n"
528
    done
529
    local userinput=""
530
    printInfo "Continue and overwrite? [y/n]\n"
531
    readUserInput "YyNn" userinput
532
    case "${userinput}" in
533
      Y|y)
534
        for pfile in ${projectfiles[*]}; do
535
          rm "$pfile" 2>&1 | tee -a $LOG_FILE
536
        done
537
        ;;
538
      N|n)
539
        printWarning "Project generation aborted by user\n"
540
        return 1
541
        ;;
542
      *)
543
        printError "unexpected input: ${userinput}\n"
544
        return 999
545
        ;;
546
    esac
547
  fi
548

    
549
  # print message
550
  printf "\n"
551
  printInfo "generating QtCreator project files for all modules...\n"
552

    
553
  # retrieve absolute GCC include path
554
  if [ -z "$gccincludedir" ]; then
555
    retrieveGccIncludeDir gccincludedir
556
  fi
557

    
558
  # iterate over all modules
559
  local retval=1
560
  for module in ${modules[@]}; do
561
    if [ $retval != 0 ]; then
562
      printf "\n"
563
    fi
564
    createModuleProject modules[@] --module="$module" --path="$projectsdir" --gcc="$gccincludedir"
565
    retval=$?
566
  done
567

    
568
  return 0
569
}
570

    
571
### delete project files #######################################################
572
# Deletes all project files and optionally .user files, too.
573
#
574
# usage:      deleteProjects [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|-wipe]
575
# arguments:  -p, --path <path>
576
#                 Path where to delete the project files.
577
#             -m, --module <module>
578
#                 Module name for which the project files shall be deleted.
579
#             -o, --out <var>
580
#                 Variable to store the path to.
581
#             -w, --wipe
582
#                 Delete .user files as well.
583
# return:
584
#  -  0: no error
585
#
586
function deleteProjects {
587
  local modulename=""
588
  local projectdir=""
589
  local outvar=""
590
  local wipe=false
591
  local files=()
592

    
593
  # parse arguments
594
  local otherargs=()
595
  while [ $# -gt 0 ]; do
596
    if ( parseIsOption $1 ); then
597
      case "$1" in
598
        -p=*|--path=*)
599
          projectdir=$(realpath "${1#*=}"); shift 1;;
600
        -p|--path)
601
          projectdir=$(realpath "$2"); shift 2;;
602
        -m=*|--module=*)
603
          modulename="${1#*=}"; shift 1;;
604
        -m|--module)
605
          modulename="${2}"; shift 2;;
606
        -o=*|--out=*)
607
          outvar=${1#*=}; shift 1;;
608
        -o|--out)
609
          outvar=$2; shift 2;;
610
        -w|--wipe)
611
          wipe=true; shift 1;;
612
        *)
613
          printError "invalid option: $1\n"; shift 1;;
614
      esac
615
    else
616
      otherargs+=("$1")
617
      shift 1
618
    fi
619
  done
620

    
621
  # read absolute project directory if required
622
  if [ -z "$projectdir" ]; then
623
    getProjectDir projectdir
624
  fi
625

    
626
  # list all files to be deleted
627
  if [ -z "$modulename" ]; then
628
    if [ $wipe != true ]; then
629
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|cflags|cxxflags)$"))
630
    else
631
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|cflags|cxxflags|creator(\.user(\..+)?)?)$"))
632
    fi
633
  else
634
    if [ $wipe != true ]; then
635
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^${modulename}\.(includes|files|config|creator|cflags|cxxflags)$"))
636
    else
637
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^${modulename}\.(includes|files|config|creator|cflags|cxxflags|creator(\.user(\..+)?)?)$"))
638
    fi
639
  fi
640
  if [ ${#files[@]} != 0 ]; then
641
    printInfo "Deleting the following files:\n"
642
    for file in ${files[@]}; do
643
      printInfo "\t$(basename ${file})\n"
644
      rm ${file} 2>&1 | tee -a $LOG_FILE
645
    done
646
  else
647
    printInfo "No project files found\n"
648
  fi
649

    
650
  # store the path to the output variable, if required
651
  if [ ! -z "$outvar" ]; then
652
    eval $outvar="$projectdir"
653
  fi
654

    
655
  return 0
656
}
657

    
658
### main function of this script ###############################################
659
# Creates, deletes and wipes QtCreator project files for any module supported by AMiRo-OS.
660
#
661
# usage:      see function printHelp
662
# arguments:  see function printHelp
663
# return:     0
664
#                 No error or warning ocurred.
665
#
666
function main {
667
# print welcome/info text if not suppressed
668
  if [[ $@ != *"--noinfo"* ]]; then
669
    printWelcomeText
670
  else
671
    printf "######################################################################\n"
672
  fi
673
  printf "\n"
674

    
675
  # if --help or -h was specified, print the help text and exit
676
  if [[ $@ == *"--help"* || $@ == *"-h"* ]]; then
677
    printHelp
678
    printf "\n"
679
    quitScript
680
  fi
681

    
682
  # set log file if specified
683
  if [[ $@ == *"--log"* ]] || [[ $@ == *"--LOG"* ]]; then
684
    # get the parameter (file name)
685
    local cmdidx=1
686
    while [[ ! "${!cmdidx}" = "--log"* ]] && [[ ! "${!cmdidx}" = "--LOG"* ]]; do
687
      cmdidx=$[cmdidx + 1]
688
    done
689
    local cmd="${!cmdidx}"
690
    local logfile=""
691
    if [[ "$cmd" = "--log="* ]] || [[ "$cmd" = "--LOG="* ]]; then
692
      logfile=${cmd#*=}
693
    else
694
      local filenameidx=$((cmdidx + 1))
695
      logfile="${!filenameidx}"
696
    fi
697
    # optionally force silent appending
698
    if [[ "$cmd" = "--LOG"* ]]; then
699
      setLogFile --option=c --quiet "$logfile" LOG_FILE
700
    else
701
      setLogFile "$logfile" LOG_FILE
702
      printf "\n"
703
    fi
704
  fi
705
  # log script name
706
  printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
707

    
708
  # detect available modules and inform user
709
  local modules=()
710
  detectModules modules
711
  case "${#modules[@]}" in
712
    0)
713
      printInfo "no module has been detected\n";;
714
    1)
715
      printInfo "1 module has been detected:\n";;
716
    *)
717
      printInfo "${#modules[@]} modules have been detected:\n"
718
  esac
719
  for (( idx=0; idx<${#modules[@]}; ++idx )); do
720
    printInfo "  - ${modules[$idx]}\n"
721
  done
722
  printf "\n"
723

    
724
  # parse arguments
725
  local otherargs=()
726
  while [ $# -gt 0 ]; do
727
    if ( parseIsOption $1 ); then
728
      case "$1" in
729
        -h|--help) # already handled; ignore
730
          shift 1;;
731
        -m=*|--module=*)
732
          createModuleProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
733
        -m|--module)
734
          createModuleProject modules[@] --module="${2}"; printf "\n"; shift 2;;
735
        -a|--all)
736
          createAllProjects modules[@]; shift 1;;
737
        -c|--clean)
738
          deleteProjects; printf "\n"; shift 1;;
739
        -w|--wipe)
740
          deleteProjects --wipe; printf "\n"; shift 1;;
741
        -q|--quit)
742
          quitScript; shift 1;;
743
        --log=*|--LOG=*) # already handled; ignore
744
          shift 1;;
745
        --log|--LOG) # already handled; ignore
746
          shift 2;;
747
        --noinfo) # already handled; ignore
748
          shift 1;;
749
        *)
750
          printError "invalid option: $1\n"; shift 1;;
751
      esac
752
    else
753
      otherargs+=("$1")
754
      shift 1
755
    fi
756
  done
757

    
758
  # interactive menu
759
  while ( true ); do
760
    # main menu info prompt and selection
761
    printInfo "QtCreator setup main menu\n"
762
    printf "Please select one of the following actions:\n"
763
    printf "  [M] - create a project for a single module\n"
764
    printf "  [A] - create a project for all modules\n"
765
    printf "  [C] - clean all project files\n"
766
    printf "  [W] - wipe all project and .user files\n"
767
    printf "  [Q] - quit this setup\n"
768
    local userinput=""
769
    readUserInput "MmAaCcWwQq" userinput
770
    printf "\n"
771

    
772
    # evaluate user selection
773
    case "$userinput" in
774
      M|m)
775
        createModuleProject modules[@]; printf "\n";;
776
      A|a)
777
        createAllProjects modules[@]; printf "\n";;
778
      C|c)
779
        deleteProjects; printf "\n";;
780
      W|w)
781
        deleteProjects --wipe; printf "\n";;
782
      Q|q)
783
        quitScript;;
784
      *) # sanity check (exit with error)
785
        printError "unexpected argument: $userinput\n";;
786
    esac
787
  done
788

    
789
  exit 0
790
}
791

    
792
################################################################################
793
# SCRIPT ENTRY POINT                                                           #
794
################################################################################
795

    
796
main "$@"
797