Revision 1678f270 tools/ide/QtCreator/QtCreatorSetup.sh

View differences:

tools/ide/QtCreator/QtCreatorSetup.sh
1 1
################################################################################
2 2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3 3
# (AMiRo) platform.                                                            #
4
# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
4
# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
5 5
#                                                                              #
6 6
# This program is free software: you can redistribute it and/or modify         #
7 7
# it under the terms of the GNU General Public License as published by         #
......
263 263
  return 0
264 264
}
265 265

  
266
### check whether commands are available #######################################
267
# Checks whether the specified commands are available and can be executed.
268
#
269
# usage:      checkCommand [<command> <command> ...]
270
# arguments:  <command>
271
#                 Name of the command to check.
272
# return:     0
273
#                 All requested commands are available.
274
#             >0
275
#                 Number of requested commands that were not found.
276
#             -1
277
#                 No argument given.
278
#
279
function checkCommands {
280
  local status=0
281

  
282
  # return if no argument was specified
283
  if [ $# -eq 0 ]; then
284
    return -1
285
  fi
286

  
287
  # check all specified commands
288
  while [ $# -gt 0 ]; do
289
    command -v $1 &>/dev/null
290
    if [ $? -ne 0 ]; then
291
      printWarning "Command '$1' not available.\n"
292
      status=$((status + 1))
293
    fi
294
    shift 1
295
  done
296

  
297
  return $status
298
}
299

  
266 300
################################################################################
267 301
# SPECIFIC FUNCTIONS                                                           #
268 302
################################################################################
......
281 315
  printf "#                                                                    #\n"
282 316
  printf "######################################################################\n"
283 317
  printf "#                                                                    #\n"
284
  printf "# Copyright (c) 2016..2018  Thomas Schöpping                         #\n"
318
  printf "# Copyright (c) 2016..2019  Thomas Schöpping                         #\n"
285 319
  printf "#                                                                    #\n"
286 320
  printf "# This is free software; see the source for copying conditions.      #\n"
287 321
  printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
......
303 337
#
304 338
function printHelp {
305 339
  printInfo "printing help text\n"
306
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-c|--clean] [-w|--wipe] [--LightRing] [--PowerManagement] [--DiWheelDrive] [-a|--all] [-q|--quit] [--log=<file>]\n"
340
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [--module=<module>] [-a|--all] [-c|--clean] [-w|--wipe] [-q|--quit] [--log=<file>]\n"
307 341
  printf "\n"
308 342
  printf "options:  -h, --help\n"
309 343
  printf "              Print this help text.\n"
344
  printf "          --module=<module>\n"
345
  printf "              Create project for a single module.\n"
346
  printf "          -a, --all\n"
347
  printf "              Create projects for all modules.\n"
310 348
  printf "          -c, --clean\n"
311 349
  printf "              Delete project files.\n"
312 350
  printf "          -w, --wipe\n"
313 351
  printf "              Delete project and .user files.\n"
314
  printf "          --LightRing\n"
315
  printf "              Create project for the LightRing module.\n"
316
  printf "          --PowerManagement\n"
317
  printf "              Create project for the PowerManagement module.\n"
318
  printf "          --DiWheelDrive\n"
319
  printf "              Create project for the DiWheelDrive module.\n"
320
  printf "          -a, --all\n"
321
  printf "              Create projects for all modules.\n"
322 352
  printf "          -q, --quit\n"
323 353
  printf "              Quit the script.\n"
324 354
  printf "          --log=<file>\n"
......
374 404
  fi
375 405
}
376 406

  
377
### delete project files #######################################################
378
# Deletes all project files and optionally .user files, too.
407
### detect available modules ###################################################
408
# Detect all avalable modules supported by AMiRo-OS.
379 409
#
380
# usage:      deleteProjects [-p|--path=<path>] [-o|--out=<var>] [-w|-wipe]
381
# arguments:  -p, --path <path>
382
#                 Path where to delete the project files.
383
#             -o, --out <var>
384
#                 Variable to store the path to.
385
#             -w, --wipe
386
#                 Delete .user files as well.
387
# return:
388
#  -  0: no error
389
#  -  1: warning: function aborted by user
390
#  - -1: error: unexpected user input
391
function deleteProjects {
392
  local projectdir=""
393
  local outvar=""
394
  local wipe=false
410
# usage:      detectModules <modulearray>
411
# arguments:  <modulearray>
412
#                 Array variable to store all detected modules to.
413
# return:     n/a
414
#
415
function detectModules {
416
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
417
  local modules_detected=()
395 418

  
396
  # parse arguments
397
  local otherargs=()
398
  while [ $# -gt 0 ]; do
399
    if ( parseIsOption $1 ); then
400
      case "$1" in
401
        -p=*|--path=*)
402
          projectdir=$(realpath "${1#*=}"); shift 1;;
403
        -p|--path)
404
          projectdir=$(realpath "$2"); shift 2;;
405
        -o=*|--out=*)
406
          outvar=${1#*=}; shift 1;;
407
        -o|--out)
408
          outvar=$2; shift 2;;
409
        -w|--wipe)
410
          wipe=true; shift 1;;
411
        *)
412
          printError "invalid option: $1\n"; shift 1;;
413
      esac
414
    else
415
      otherargs+=("$1")
416
      shift 1
417
    fi
419
  # detect all available modules (via directories)
420
  for dir in $(ls -d ${modulesdir}/*/); do
421
    modules_detected[${#modules_detected[@]}]=$(basename $dir)
418 422
  done
419 423

  
420
  # print message
421
  if [ $wipe != true ]; then
422
    printInfo "deleting all QtCreator project files (*.includes, *.files, *.config, and *.creator)\n"
423
  else
424
    printInfo "deleting all QtCreator project files (*.includes, *.files, *.config, *.creator, and *.user)\n"
425
  fi
426

  
427
  # read project directory if required
428
  if [ -z "$projectdir" ]; then
429
    getProjectDir projectdir
430
  fi
431

  
432
  # remove all project files
433
  rm ${projectdir}/LightRing.includes 2>&1 | tee -a $LOG_FILE
434
  rm ${projectdir}/PowerManagement.includes 2>&1 | tee -a $LOG_FILE
435
  rm ${projectdir}/DiWheelDrive.includes 2>&1 | tee -a $LOG_FILE
436

  
437
  rm ${projectdir}/LightRing.files 2>&1 | tee -a $LOG_FILE
438
  rm ${projectdir}/PowerManagement.files 2>&1 | tee -a $LOG_FILE
439
  rm ${projectdir}/DiWheelDrive.files 2>&1 | tee -a $LOG_FILE
440

  
441
  rm ${projectdir}/LightRing.config 2>&1 | tee -a $LOG_FILE
442
  rm ${projectdir}/PowerManagement.config 2>&1 | tee -a $LOG_FILE
443
  rm ${projectdir}/DiWheelDrive.config 2>&1 | tee -a $LOG_FILE
444

  
445
  rm ${projectdir}/LightRing.creator 2>&1 | tee -a $LOG_FILE
446
  rm ${projectdir}/PowerManagement.creator 2>&1 | tee -a $LOG_FILE
447
  rm ${projectdir}/DiWheelDrive.creator 2>&1 | tee -a $LOG_FILE
448

  
449
  if [ $wipe == true ]; then
450
    rm ${projectdir}/LightRing.creator.user 2>&1 | tee -a $LOG_FILE
451
    rm ${projectdir}/PowerManagement.creator.user 2>&1 | tee -a $LOG_FILE
452
    rm ${projectdir}/DiWheelDrive.creator.user 2>&1 | tee -a $LOG_FILE
453
  fi
454

  
455
  # store the path to the output variable, if required
456
  if [ ! -z "$outvar" ]; then
457
    eval $outvar="$projectdir"
458
  fi
459

  
460
  return 0
424
  # set the output variable
425
  eval "$1=(${modules_detected[*]})"
461 426
}
462 427

  
463
### create LightRing project files #############################################
464
# Create project files for the LightRing module.
428
### create project files for a single module ###################################
429
# Create project files for a single module.
465 430
#
466
# usage:      createLightRingProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
467
# arguments:  -p, --path <path>
431
# usage:      createModuleProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
432
# arguments:  <modules>
433
#                 Array containing all modules available.
434
#             -m, --module <module>
435
#                 Name (folder name) of the module for which project files shall be generated.
436
#             -p, --path <path>
468 437
#                 Path where to create the project files.
469 438
#             --gcc=<path>
470 439
#                 Path to the GCC include directory.
......
472 441
#                 Variable to store the path to.
473 442
#             --gccout=<var>
474 443
#                 Variable to store the path to the GCC include directory to.
444
#                 If this optional arguments is absent, ths function will ask for user input.
475 445
# return:     0
476 446
#                 No error or warning occurred.
447
#             1
448
#                 Aborted by user.
449
#             -1
450
#                 No modules available.
451
#             -2
452
#                 The specified <module> could not be found.
453
#             -3
454
#                 Parsing the project for the specified module failed.
455
#             -4
456
#                 Missing dependencies.
477 457
#
478
function createLightRingProject {
458
function createModuleProject {
479 459
  local userdir=$(pwd)
460
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
461
  local modules=("${!1}")
462
  local module=""
463
  local moduleidx=""
480 464
  local projectdir=""
481 465
  local gccincludedir=""
482 466
  local outvar=""
483 467
  local gccoutvar=""
484 468

  
469
  # check dependencies
470
  checkCommands make
471
  if [ $? -ne 0 ]; then
472
    printError "Missing dependencies detected.\n"
473
    return -4
474
  fi
475

  
485 476
  # parse arguments
486 477
  local otherargs=()
487 478
  while [ $# -gt 0 ]; do
488 479
    if ( parseIsOption $1 ); then
489 480
      case "$1" in
481
        -m=*|--module=*)
482
          module="${1#*=}"; shift 1;;
483
        -m|--module)
484
          module="$2"; shift 2;;
490 485
        -p=*|--path=*)
491 486
          projectdir=$(realpath "${1#*=}"); shift 1;;
492 487
        -p|--path)
......
512 507
    fi
513 508
  done
514 509

  
515
  # print message
516
  printInfo "creating QtCreator project files for the LightRing module...\n"
510
  # sanity check for the modules variable
511
  if [ -z "${modules[*]}" ]; then
512
    printError "no modules available\n"
513
    return -1
514
  fi
515

  
516
  # select module
517
  if [ -z $module ]; then
518
    # list all available modules
519
    printInfo "choose a module or type 'A' to abort:\n"
520
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
521
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
522
    done
523
    # read user input
524
    printLog "read user selection\n"
525
    local userinput=""
526
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; do
527
      read -p "your selection: " -e userinput
528
      printLog "user selection: $userinput\n"
529
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
530
        printWarning "Please enter an integer between 1 and ${#modules[@]} or 'A' to abort.\n"
531
      fi
532
    done
533
    if [[ "$userinput" =~ ^[Aa]$ ]]; then
534
      printWarning "aborted by user\n"
535
      return 1
536
    fi
537
    # store selection
538
    moduleidx=$(($userinput - 1))
539
    module="${modules[$moduleidx]}"
540
    printf "\n"
541
  else
542
    # search all modules for the selected one
543
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
544
      if [ "${modules[$idx]}" = "$module" ]; then
545
        moduleidx=$idx
546
        break
547
      fi
548
    done
549
    # error if the module could not be found
550
    if [ -z $moduleidx ]; then
551
      printError "module ($module) not available\n"
552
      return -2
553
    fi
554
  fi
517 555

  
518 556
  # read absolute project directory if required
519 557
  if [ -z "$projectdir" ]; then
520 558
    getProjectDir projectdir
559
    printf "\n"
560
  fi
561

  
562
  # check for existing project files
563
  local projectfiles="$(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$")"
564
  IFS=$'\n'; projectfiles=($projectfiles); unset IFS
565
  if [ ! -z "${projectfiles[*]}" ]; then
566
    printWarning "The following files will be overwritten:\n"
567
    for pfile in ${projectfiles[@]}; do
568
      printWarning "\t$(basename $pfile)\n"
569
    done
570
    local userinput=""
571
    printInfo "Continue and overwrite? [y/n]\n"
572
    readUserInput "YyNn" userinput
573
    case "$userinput" in
574
      Y|y)
575
        ;;
576
      N|n)
577
        printWarning "Project generation for ${module} module aborted by user\n"
578
        return 1
579
        ;;
580
      *)
581
        printError "unexpected input: ${userinput}\n"; return -999;;
582
    esac
583
    printf "\n"
521 584
  fi
522 585

  
523
  # retrieve absolute GCC include dir
586
  # print message
587
  printInfo "generating QtCreator project files for the $module module...\n"
588

  
589
  # retrieve absolute GCC include path
524 590
  if [ -z "$gccincludedir" ]; then
525 591
    retrieveGccIncludeDir gccincludedir
526 592
  fi
527 593

  
528
  # move to project directory
529
  cd $projectdir
594
  # change to project directory
595
  cd "$projectdir"
530 596

  
531
  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
597
  # run make, but only run the GCC preprocessor and produce no binaries
532 598
  local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
533
  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
534
  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
535
  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
536

  
537
  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
538
  find $gccincludedir -type d > ${projectdir}/LightRing.includes
539
  echo $amiroosrootdir >> ${projectdir}/LightRing.includes
540
  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/PowerManagement\|/DiWheelDrive" >> ${projectdir}/LightRing.includes
541
  find $amiroosrootdir/core -type d >> ${projectdir}/LightRing.includes
542
  find $amiroosrootdir/unittests -type d >> ${projectdir}/LightRing.includes
543
  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/LightRing.includes
544
  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F1xx)$" >> ${projectdir}/LightRing.includes
545
  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/LightRing.includes
546
  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/LightRing.includes
547
  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F1xx)$" >> ${projectdir}/LightRing.includes
548
  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/LightRing.includes
549
  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/LightRing.includes
550
  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/LightRing.includes
551
  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(CANv1|DACv1|DMAv1|EXTIv1|GPIOv1|I2Cv1|RTCv1|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F1xx))$" >> ${projectdir}/LightRing.includes
552
  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/LightRing.includes
553
  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/LightRing.includes
554
  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/LightRing.includes
555
  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/LightRing.includes
556
  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/LightRing.includes
557
  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/LightRing.includes
558
  # generate a file that specifies all files
559
  echo -n "" > ${projectdir}/LightRing.files
560
  for path in `cat ${projectdir}/LightRing.includes`; do
561
    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
562
      grep -Ev "^.*((/arm-none-eabi/)|(PowerManagement)|(DiWheelDrive)).*$" |
563
      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
564
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F1xx/((stm32f1[^0x])|(stm32f10[^3])|(stm32f103[^x])|(stm32f103x[^e])).*$" |
565
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^3A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
566
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
567
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
568
      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
569
      grep -Ev "^${chibiosrootdir}/os/hal/ports/STM32/STM32F1xx/.*f10[^3].*$" |
570
      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/LightRing.files;
599
  local sourcefiles=()
600
  local sourcefile=""
601
  local parse_state="WAIT_FOR_INCLUDE_OR_COMPILE"
602
  # capture all output from make and GCC and append the return value of make as last line
603
  printInfo "processing project (this may take a while)...\n"
604
  local rawout=$(make --directory ${amiroosrootdir}/modules/${module} --always-make USE_OPT="-v -E -H" USE_VERBOSE_COMPILE="no" OUTFILES="" 2>&1 && echo $?)
605
  # check whether the make call was successfull
606
  if [[ $(echo "${rawout}" | tail -n 1) != "0" ]]; then
607
    printError "executing 'make' in module directory failed\n"
608
    cd "$userdir"
609
    return -3
610
  else
611
    # cleanup
612
    make --directory ${amiroosrootdir}/modules/${module} clean &>/dev/null
613
  fi
614
  # extract file names from raw output
615
  IFS=$'\n'; rawout=($rawout); unset IFS
616
  for line in "${rawout[@]}"; do
617
    case $parse_state in
618
      WAIT_FOR_INCLUDE_OR_COMPILE)
619
        # lines stating included files look like:
620
        # ... <../relative/path/to/file>
621
        if [[ "$line" =~ ^\.+[[:blank:]].+\..+$ ]]; then
622
          sourcefile=${line##* }
623
          if [[ ! "$sourcefile" =~ ^/ ]]; then
624
            sourcefile=$(realpath ${amiroosrootdir}/modules/${module}/${sourcefile})
625
          fi
626
          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
627
        # whenever the next source file is processed, a message appears like:
628
        # Compining <filnemame>
629
        elif [[ "$line" =~ ^Compiling[[:blank:]].+\..+$ ]]; then
630
          printf "."
631
          sourcefile=${line##* }
632
          parse_state="WAIT_FOR_COMPILERCALL"
633
        fi;;
634
      WAIT_FOR_COMPILERCALL)
635
        # wait for the actual call of the compiler to retrieve the full path to the source file
636
        if [[ "$line" == *${sourcefile}* ]]; then
637
          line="${line%%${sourcefile}*}${sourcefile}"
638
          sourcefile=${line##* }
639
          sourcefile=$(realpath ${amiroosrootdir}/modules/${module}/${line##* })
640
          sourcefiles[${#sourcefiles[@]}]="$sourcefile"
641
          parse_state="WAIT_FOR_INCLUDE_OR_COMPILE"
642
        fi;;
643
    esac
644
  done
645
  unset rawout
646
  printf "\n"
647
  # sort and remove duplicates
648
  IFS=$'\n'; sourcefiles=($(sort --unique <<< "${sourcefiles[*]}")); unset IFS
649

  
650
  # extract include paths
651
  local includes=()
652
  for source in ${sourcefiles[*]}; do
653
    includes[${#includes[@]}]="$(dirname ${source})"
654
  done
655
  # sort and remove duplicates
656
  IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
657

  
658
  # generate the .files file, containing all source files
659
  echo "" > ${projectdir}/${module}.includes
660
  for inc in ${includes[*]}; do
661
    echo "$inc" >> ${projectdir}/${module}.includes
662
  done
663
  # generate the .incldues file, containing all include paths
664
  echo "" > ${projectdir}/${module}.files
665
  for source in ${sourcefiles[*]}; do
666
    # skip GCC files
667
    if [[ ! "$source" =~ .*/gcc.* ]]; then
668
      echo "$source" >> ${projectdir}/${module}.files
669
    fi
571 670
  done
572
  # generate a default project configuration file if none exists so far
573
  if [ ! -f ${projectdir}/LightRing.config ]; then
574
    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/LightRing.config
575
    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/LightRing.config
671
  # generate a default project configuration file if it doesn't exist yet
672
  if [ ! -f ${projectdir}/${module}.config ]; then
673
    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/${module}.config
674
    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/${module}.config
576 675
  fi
577
  # generate a default .creator file if none exists so far
578
  if [ ! -f ${projectdir}/LightRing}.creator ]; then
579
    echo "[general]" > ${projectdir}/LightRing.creator
676
  # generate a default .creator file if it doesn't exist yet
677
  if [ ! -f ${projectdir}/${module}.creator ]; then
678
    echo "[general]" > ${projectdir}/${module}.creator
580 679
  fi
581 680

  
582 681
  # go back to user directory
......
593 692
  return 0
594 693
}
595 694

  
596
### create PowerManagement project files #######################################
597
# Create project files for the PowerManagement module.
695
### create project files for all modules #######################################
696
# Create project files for all modules.
598 697
#
599
# usage:      createPowerManagementProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
600
# arguments:  -p, --path <path>
698
# usage:      createAllProjects <modules> [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
699
# arguments:  <modules>
700
#                 Array containing all modules available.
701
#             -p, --path <path>
601 702
#                 Path where to create the project files.
602 703
#             --gcc=<path>
603 704
#                 Path to the GCC include directory.
......
605 706
#                 Variable to store the path to.
606 707
#             --gccout=<var>
607 708
#                 Variable to store the path to the GCC include directory to.
709
#                 If this optional arguments is absent, ths function will ask for user input.
608 710
# return:     0
609 711
#                 No error or warning occurred.
712
#             1
713
#                 Aborted by user.
714
#             -1
715
#                 No modules available.
610 716
#
611
function createPowerManagementProject {
612
  local userdir=$(pwd)
717
function createAllProjects {
718
  local modules=("${!1}")
613 719
  local projectdir=""
614 720
  local gccincludedir=""
615 721
  local outvar=""
......
645 751
    fi
646 752
  done
647 753

  
648
  # print message
649
  printInfo "creating QtCreator project files for the PowerManagement module...\n"
754
  # sanity check for the modules variable
755
  if [ -z "${modules[*]}" ]; then
756
    printError "no modules available\n"
757
    return -1
758
  fi
650 759

  
651 760
  # read absolute project directory if required
652 761
  if [ -z "$projectdir" ]; then
653 762
    getProjectDir projectdir
654 763
  fi
655 764

  
656
  # retrieve absolute GCC include dir
657
  if [ -z "$gccincludedir" ]; then
658
    retrieveGccIncludeDir gccincludedir
659
  fi
660

  
661
  # move to project directory
662
  cd $projectdir
663

  
664
  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
665
  local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
666
  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
667
  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
668
  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
669

  
670
  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
671
  find $gccincludedir -type d > ${projectdir}/PowerManagement.includes
672
  echo $amiroosrootdir >> ${projectdir}/PowerManagement.includes
673
  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/LightRing\|/DiWheelDrive" >> ${projectdir}/PowerManagement.includes
674
  find $amiroosrootdir/core -type d >> ${projectdir}/PowerManagement.includes
675
  find $amiroosrootdir/unittests -type d >> ${projectdir}/PowerManagement.includes
676
  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/PowerManagement.includes
677
  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F4xx)$" >> ${projectdir}/PowerManagement.includes
678
  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/PowerManagement.includes
679
  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/PowerManagement.includes
680
  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F4xx)$" >> ${projectdir}/PowerManagement.includes
681
  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/PowerManagement.includes
682
  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/PowerManagement.includes
683
  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/PowerManagement.includes
684
  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(ADCv2|CANv1|DACv1|DMAv2|EXTIv1|GPIOv2|I2Cv1|MACv1|OTGv1|RTCv2|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F4xx))$" >> ${projectdir}/PowerManagement.includes
685
  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/PowerManagement.includes
686
  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/PowerManagement.includes
687
  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/PowerManagement.includes
688
  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/PowerManagement.includes
689
  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/PowerManagement.includes
690
  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/PowerManagement.includes
691
  # generate a file that specifies all files
692
  echo -n "" > ${projectdir}/PowerManagement.files
693
  for path in `cat ${projectdir}/PowerManagement.includes`; do
694
    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
695
      grep -Ev "^.*((/arm-none-eabi/)|(LightRing)|(DiWheelDrive)).*$" |
696
      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
697
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F4xx/((stm32f4[^0x])|(stm32f40[^5])).*$" |
698
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^4A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
699
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
700
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
701
      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
702
      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/PowerManagement.files;
765
  # check for existing project files
766
  local projectfiles=()
767
  for module in ${modules[@]}; do
768
    local pfiles="$(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$")"
769
    IFS=$'\n'; pfiles=($pfiles); unset IFS
770
    projectfiles=( ${projectfiles[*]} ${pfiles[*]} )
703 771
  done
704
  # generate a default project configuration file if none exists so far
705
  if [ ! -f ${projectdir}/PowerManagement.config ]; then
706
    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/PowerManagement.config
707
    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/PowerManagement.config
708
  fi
709
  # generate a default .creator file if none exists so far
710
  if [ ! -f ${projectdir}/PowerManagement.creator ]; then
711
    echo "[general]" > ${projectdir}/PowerManagement.creator
772
  if [ ! -z "${projectfiles[*]}" ]; then
773
    printWarning "The following files will be removed:\n"
774
    for pfile in ${projectfiles[@]}; do
775
      printWarning "\t$(basename $pfile)\n"
776
    done
777
    local userinput=""
778
    printInfo "Continue and overwrite? [y/n]\n"
779
    readUserInput "YyNn" userinput
780
    case "${userinput}" in
781
      Y|y)
782
        for pfile in ${projectfiles[*]}; do
783
          rm "$pfile"
784
        done
785
        ;;
786
      N|n)
787
        printWarning "Project generation aborted by user\n"
788
        return 1
789
        ;;
790
      *)
791
        printError "unexpected input: ${userinput}\n"
792
        return 999
793
        ;;
794
    esac
712 795
  fi
713 796

  
714
  # go back to user directory
715
  cd $userdir
797
  # print message
798
  printf "\n"
799
  printInfo "generating QtCreator project files for all modules...\n"
716 800

  
717
  # fill the output variables
718
  if [ ! -z "$outvar" ]; then
719
    eval $outvar="$projectdir"
720
  fi
721
  if [ ! -z "$gccoutvar" ]; then
722
    eval $gccoutvar="$gccincludedir"
801
  # retrieve absolute GCC include path
802
  if [ -z "$gccincludedir" ]; then
803
    retrieveGccIncludeDir gccincludedir
723 804
  fi
724 805

  
806
  # iterate over all modules
807
  local retval=1
808
  for module in ${modules[@]}; do
809
    if [ $retval != 0 ]; then
810
      printf "\n"
811
    fi
812
    createModuleProject modules[@] --module="$module" --path="$projectdir" --gcc="$gccincludedir"
813
    retval=$?
814
  done
815

  
725 816
  return 0
726 817
}
727 818

  
728
### create DiWheelDrive project files ##########################################
729
# Create project files for the DiWheelDrive module.
819
### delete project files #######################################################
820
# Deletes all project files and optionally .user files, too.
730 821
#
731
# usage:      createDiWheelDriveProject [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
822
# usage:      deleteProjects [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|-wipe]
732 823
# arguments:  -p, --path <path>
733
#                 Path where to create the project files.
734
#             --gcc=<path>
735
#                 Path to the GCC include directory.
824
#                 Path where to delete the project files.
825
#             -m, --module <module>
826
#                 Module name for which the project files shall be deleted.
736 827
#             -o, --out <var>
737 828
#                 Variable to store the path to.
738
#             --gccout=<var>
739
#                 Variable to store the path to the GCC include directory to.
740
# return:     0
741
#                 No error or warning occurred.
829
#             -w, --wipe
830
#                 Delete .user files as well.
831
# return:
832
#  -  0: no error
742 833
#
743
function createDiWheelDriveProject {
744
  local userdir=$(pwd)
834
function deleteProjects {
835
  local modulename=""
745 836
  local projectdir=""
746
  local gccincludedir=""
747 837
  local outvar=""
748
  local gccoutvar=""
838
  local wipe=false
839
  local files=""
749 840

  
750 841
  # parse arguments
751 842
  local otherargs=()
......
756 847
          projectdir=$(realpath "${1#*=}"); shift 1;;
757 848
        -p|--path)
758 849
          projectdir=$(realpath "$2"); shift 2;;
759
        --gcc=*)
760
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
761
        --gcc)
762
          gccincludedir=$(realpath "$2"); shift 2;;
850
        -m=*|--module=*)
851
          modulename="${1#*=}"; shift 1;;
852
        -m|--module)
853
          modulename="${2}"; shift 2;;
763 854
        -o=*|--out=*)
764 855
          outvar=${1#*=}; shift 1;;
765 856
        -o|--out)
766 857
          outvar=$2; shift 2;;
767
        --gccout=*)
768
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
769
        --gccout)
770
          gccoutvar=$(realpath "$2"); shift 2;;
858
        -w|--wipe)
859
          wipe=true; shift 1;;
771 860
        *)
772 861
          printError "invalid option: $1\n"; shift 1;;
773 862
      esac
......
777 866
    fi
778 867
  done
779 868

  
780
  # print message
781
  printInfo "creating QtCreator project files for the DiWheelDrive module...\n"
782

  
783 869
  # read absolute project directory if required
784 870
  if [ -z "$projectdir" ]; then
785 871
    getProjectDir projectdir
786 872
  fi
787 873

  
788
  # retrieve absolute GCC include dir
789
  if [ -z "$gccincludedir" ]; then
790
    retrieveGccIncludeDir gccincludedir
791
  fi
792

  
793
  # move to project directory
794
  cd $projectdir
795

  
796
  # AMiRo-OS, ChibiOS, AMiRo-BLT and AMiRo-LLD relative root directories
797
  local amiroosrootdir=$(realpath $(dirname ${BASH_SOURCE[0]})/../../..)
798
  local chibiosrootdir=$(realpath ${amiroosrootdir}/kernel/ChibiOS)
799
  local amirobltrootdir=$(realpath ${amiroosrootdir}/bootloader/AMiRo-BLT)
800
  local amirolldrootdir=$(realpath ${amiroosrootdir}/periphery-lld/AMiRo-LLD)
801

  
802
  # generate a file that contains all subdirectories as includes (but ignore hidden and documentation directories)
803
  find $gccincludedir -type d > ${projectdir}/DiWheelDrive.includes
804
  echo $amiroosrootdir >> ${projectdir}/DiWheelDrive.includes
805
  find $amiroosrootdir/modules -type d | grep -v "/doc\|/build\|/.dep\|/LightRing\|/PowerManagement" >> ${projectdir}/DiWheelDrive.includes
806
  find $amiroosrootdir/core -type d >> ${projectdir}/DiWheelDrive.includes
807
  find $amiroosrootdir/unittests -type d >> ${projectdir}/DiWheelDrive.includes
808
  find $chibiosrootdir -type d | grep -E "/os/common/abstractions/cmsis_os$" >> ${projectdir}/DiWheelDrive.includes
809
  find $chibiosrootdir -type d | grep -E "/os/common/ext/CMSIS/(include|ST/STM32F1xx)$" >> ${projectdir}/DiWheelDrive.includes
810
  find $chibiosrootdir -type d | grep -E "/os/common/oslib/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
811
  find $chibiosrootdir -type d | grep -E "/os/common/ports/ARMCMx(/compilers/GCC)?$" >> ${projectdir}/DiWheelDrive.includes
812
  find $chibiosrootdir -type d | grep -E "/os/common/startup/ARMCMx/(compilers/GCC|devices/STM32F1xx)$" >> ${projectdir}/DiWheelDrive.includes
813
  find $chibiosrootdir -type d | grep -E "/os/hal/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
814
  find $chibiosrootdir -type d | grep -E "/os/hal/lib/streams" >> ${projectdir}/DiWheelDrive.includes
815
  find $chibiosrootdir -type d | grep -E "/os/hal/osal/(lib|rt)$" >> ${projectdir}/DiWheelDrive.includes
816
  find $chibiosrootdir -type d | grep -E "/os/hal/ports/(common/ARMCMx|STM32/(LLD/(CANv1|DACv1|DMAv1|EXTIv1|GPIOv1|I2Cv1|RTCv1|SDIOv1|SPIv1|TIMv1|USARTv1|USBv1|xWDGv1)|STM32F1xx))$" >> ${projectdir}/DiWheelDrive.includes
817
  find $chibiosrootdir -type d | grep -E "/os/license$" >> ${projectdir}/DiWheelDrive.includes
818
  find $chibiosrootdir -type d | grep -E "/os/rt/(include|src)$" >> ${projectdir}/DiWheelDrive.includes
819
  find $chibiosrootdir -type d | grep -E "/test/(lib|rt/source/test)$" >> ${projectdir}/DiWheelDrive.includes
820
  find $amirobltrootdir -type d | grep -E "/Target/Source/AMiRo$" >> ${projectdir}/DiWheelDrive.includes
821
  echo "$(realpath ${amirolldrootdir}/..)" >> ${projectdir}/DiWheelDrive.includes
822
  find $amirolldrootdir -type d | grep -v "/doc" >> ${projectdir}/DiWheelDrive.includes
823
  # generate a file that specifies all files
824
  echo -n "" > ${projectdir}/DiWheelDrive.files
825
  for path in `cat ${projectdir}/DiWheelDrive.includes`; do
826
    find $path -maxdepth 1 -type f \( ! -iname ".*" \) |
827
      grep -Ev "^.*((/arm-none-eabi/)|(LightRing)|(PowerManagement)).*$" |
828
      grep -E  "^.*(\.s|\.S|\.h|\.c|\.hpp|\.cpp|\.tpp|\.ld)$" |
829
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/ST/STM32F1xx/((stm32f1[^0x])|(stm32f10[^3])|(stm32f103[^x])|(stm32f103x[^e])).*$" |
830
      grep -Ev "^${chibiosrootdir}/os/common/ext/CMSIS/include/((core_[^c])|(core_c[^m])|(core_cm[^3A-Za-z])|(cmsis_[^g])|(cmsis_g[^c]|(cmsis_gc[^c])))" |
831
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/chcore_v[^7]m.*$" |
832
      grep -Ev "^${chibiosrootdir}/os/common/ports/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
833
      grep -Ev "^${chibiosrootdir}/os/common/startup/ARMCMx/compilers/GCC/.*_v[^7]m.*$" |
834
      grep -Ev "^${chibiosrootdir}/os/hal/ports/STM32/STM32F1xx/.*f10[^3].*$" |
835
      grep -Ev "^${amirobltrootdir}/Target/Source/AMiRo/helper.*$" >> ${projectdir}/DiWheelDrive.files;
836
  done
837
  # generate a default project configuration file if none exists so far
838
  if [ ! -f ${projectdir}/DiWheelDrive.config ]; then
839
    echo "// Add predefined macros for your project here. For example:" > ${projectdir}/DiWheelDrive.config
840
    echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/DiWheelDrive.config
874
  # list all files to be deleted
875
  if [ -z "$modulename" ]; then
876
    if [ $wipe != true ]; then
877
      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator)$")
878
    else
879
      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|creator\.user)$")
880
    fi
881
  else
882
    if [ $wipe != true ]; then
883
      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.${modulename}\.(includes|files|config|creator)$")
884
    else
885
      files=$(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.${modulename}\.(includes|files|config|creator|creator\.user)$")
886
    fi
841 887
  fi
842
  # generate a default .creator file if none exists so far
843
  if [ ! -f ${projectdir}/DiWheelDrive.creator ]; then
844
    echo "[general]" > ${projectdir}/DiWheelDrive.creator
888
  if [ ! -z "$files" ]; then
889
    printInfo "Deleting the following files:\n"
890
    while read line; do
891
      printInfo "\t$(basename ${line})\n"
892
      rm ${line} 2>&1 | tee -a $LOG_FILE
893
    done <<< "${files}"
894
  else
895
    printInfo "No project files found\n"
845 896
  fi
846 897

  
847
  # go back to user directory
848
  cd $userdir
849

  
850
  # fill the output variables
898
  # store the path to the output variable, if required
851 899
  if [ ! -z "$outvar" ]; then
852 900
    eval $outvar="$projectdir"
853 901
  fi
854
  if [ ! -z "$gccoutvar" ]; then
855
    eval $gccoutvar="$gccincludedir"
856
  fi
857

  
858
  return 0
859
}
860

  
861
### create project files for all modules #######################################
862
# Create project files for all modules.
863
#
864
# usage:      createAllProjects
865
# arguments:  n/a
866
# return:     0
867
#                 No error or warning occurred.
868
#
869
function createAllProjects {
870
  # print message
871
  printInfo "creating QtCreator project files for the DiWheelDrive module...\n"
872

  
873
  # read project directory
874
  local projectdir=""
875
  getProjectDir projectdir
876
  printInfo "files will be created in $projectdir\n"
877

  
878
  # retrieve gcc-arm-none-eabi include dir
879
  retrieveGccIncludeDir gccincludedir
880

  
881
  # create projects
882
  createLightRingProject --path="$projectdir" --gcc="$gccincludedir"
883
  createPowerManagementProject --path="$projectdir" --gcc="$gccincludedir"
884
  createDiWheelDriveProject --path="$projectdir" --gcc="$gccincludedir"
885 902

  
886 903
  return 0
887 904
}
......
936 953
  # log script name
937 954
  printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
938 955

  
956
  # detect available modules and inform user
957
  local modules=()
958
  detectModules modules
959
  case "${#modules[@]}" in
960
    0)
961
      printInfo "no module has been detected\n";;
962
    1)
963
      printInfo "1 module has been detected:\n";;
964
    *)
965
      printInfo "${#modules[@]} modules have been detected:\n"
966
  esac
967
  for (( idx=0; idx<${#modules[@]}; ++idx )); do
968
    printInfo "  - ${modules[$idx]}\n"
969
  done
970
  printf "\n"
971

  
939 972
  # parse arguments
940 973
  local otherargs=()
941 974
  while [ $# -gt 0 ]; do
......
943 976
      case "$1" in
944 977
        -h|--help) # already handled; ignore
945 978
          shift 1;;
979
        -m=*|--module=*)
980
          createModuleProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
981
        -m*|--module*)
982
           createModuleProject modules[@] --module="${2}"; printf "\n"; shift 2;;
983
        -a|--all)
984
           createAllProjects modules[@]; shift 1;;
946 985
        -c|--clean)
947 986
          deleteProjects; printf "\n"; shift 1;;
948 987
        -w|--wipe)
949 988
          deleteProjects --wipe; printf "\n"; shift 1;;
950
        --LightRing)
951
          createLightRingProject; printf "\n"; shift 1;;
952
        --PowerManagement)
953
          createPowerManagementProject; printf "\n"; shift 1;;
954
        --DiWheelDrive)
955
          createDiWheelDriveProject; printf "\n"; shift 1;;
956
        -a|--all)
957
          createAllProjects; printf "\n"; shift 1;;
958 989
        -q|--quit)
959 990
          quitScript; shift 1;;
960 991
        --log=*|--LOG=*) # already handled; ignore
......
977 1008
    # main menu info prompt and selection
978 1009
    printInfo "QtCreator setup main menu\n"
979 1010
    printf "Please select one of the following actions:\n"
980
    printf "  [C] - clean project files\n"
981
    printf "  [W] - wipe project and .user files\n"
982
    printf "  [L] - create a project for the LightRing module\n"
983
    printf "  [P] - create a project for the PowerManagement module\n"
984
    printf "  [D] - create a project for the DiWheelDrive module\n"
1011
    printf "  [M] - create a project for a single module\n"
985 1012
    printf "  [A] - create a project for all modules\n"
1013
    printf "  [C] - clean all project files\n"
1014
    printf "  [W] - wipe all project and .user files\n"
986 1015
    printf "  [Q] - quit this setup\n"
987 1016
    local userinput=""
988
    readUserInput "CcWwLlPpDdAaQq" userinput
1017
    readUserInput "MmAaCcWwQq" userinput
989 1018
    printf "\n"
990 1019

  
991 1020
    # evaluate user selection
992 1021
    case "$userinput" in
1022
      M|m)
1023
        createModuleProject modules[@]; printf "\n";;
1024
      A|a)
1025
        createAllProjects modules[@]; printf "\n";;
993 1026
      C|c)
994 1027
        deleteProjects; printf "\n";;
995 1028
      W|w)
996 1029
        deleteProjects --wipe; printf "\n";;
997
      L|l)
998
        createLightRingProject; printf "\n";;
999
      P|p)
1000
        createPowerManagementProject; printf "\n";;
1001
      D|d)
1002
        createDiWheelDriveProject; printf "\n";;
1003
      A|a)
1004
        createAllProjects; printf "\n";;
1005 1030
      Q|q)
1006 1031
        quitScript;;
1007 1032
      *) # sanity check (exit with error)

Also available in: Unified diff