buildLibrary.sh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/bin/bash
  2. # Compile all cpp files in a folder and all of its sub-folders into a static library using the GNU c++ compiler
  3. # The global command for running the compiler (tested with g++ and clang++)
  4. COMPILER=$1
  5. # The root of each folder containing source files
  6. SOURCE_FOLDERS=$2
  7. # The target folder where the library will be created
  8. TARGET=$3
  9. # The name of your library without any path nor extension
  10. LIBRARY_NAME=$4
  11. OBJECT_POSTFIX="_${LIBRARY_NAME}_TEMP.o"
  12. # Compiler flags
  13. COMPILER_FLAGS=$5
  14. # Use CLEAN to recompile everything
  15. # Use LAZY to only recompile if the source folder itself has changed
  16. # If the library depends on anything outside of its folder that changes, lazy compilation will fail
  17. # If you change modes a lot and compiler versions a lot, multiple temporary folders may be useful
  18. BUILD_METHOD=$6
  19. LIBRARY_FILENAME=${TARGET}/${LIBRARY_NAME}.a
  20. SUM_FILENAME=${TARGET}/${LIBRARY_NAME}.md5
  21. if [ ${BUILD_METHOD} = CLEAN ]
  22. then
  23. echo "Clean building ${LIBRARY_NAME}"
  24. # Remove the old library when clean building
  25. rm -f ${LIBRARY_FILENAME}
  26. fi
  27. if [ ${BUILD_METHOD} = LAZY ]
  28. then
  29. echo "Lazy building ${LIBRARY_NAME}"
  30. # Cat takes a filename and returns the content
  31. OLD_SUM="$(cat ${SUM_FILENAME})"
  32. # Use tar to create an archive and apply md5sum on the archive
  33. NEW_SUM="$(tar cf - ${SOURCE_FOLDERS} | md5sum)"
  34. # Remove extra characters from the result
  35. NEW_SUM=$(echo $NEW_SUM | tr -d " \t\n\r-")
  36. echo " Old md5 checksum: ${OLD_SUM}"
  37. echo " New md5 checksum: $NEW_SUM"
  38. # Compare new and old checksum
  39. # Placed in quotes to prevent taking internal spaces as argument separators
  40. if [ "${NEW_SUM}" != "${OLD_SUM}" ]
  41. then
  42. echo " Checksums didn't match. Rebuilding whole library to be safe."
  43. rm -f ${LIBRARY_FILENAME}
  44. fi
  45. # Clear the checksum in case of aborting compilation
  46. echo "Compilation not completed..." > ${SUM_FILENAME}
  47. fi
  48. # Check if the target library already exists
  49. if [ ! -f ${LIBRARY_FILENAME} ]
  50. then
  51. # Argument: $1 as the folder to compile recursively
  52. compileFolder() {
  53. if [ ! -d "$1" ]; then
  54. echo "Failed to compile files in $1 because the folder does not exist!"
  55. exit 1
  56. fi
  57. # Compile files in the folder
  58. for file in "$1"/*.cpp
  59. do
  60. [ -e $file ] || continue
  61. # Get name without path
  62. name=${file##*/}
  63. # Get name without extension nor path
  64. base=${name%.cpp}
  65. echo " C++ ${file}"
  66. ${COMPILER} ${COMPILER_FLAGS} -Wall -c ${file} -o ${TARGET}/${base}${OBJECT_POSTFIX}
  67. if [ $? -ne 0 ]
  68. then
  69. echo "Failed to compile ${file}!"
  70. exit 1
  71. fi
  72. done
  73. # Recursively compile other folders
  74. for folder in "$1"/*
  75. do
  76. if [ -d "$folder" ]
  77. then
  78. compileFolder "$folder"
  79. fi
  80. done
  81. }
  82. # Split the space separated folders into an array
  83. OLD_IFS="${IFS}"
  84. IFS=" "
  85. read -ra FOLDER_ARRAY <<< "$SOURCE_FOLDERS"
  86. IFS="${OLD_IFS}" # IFS must be brought back to avoid crashing the compiler
  87. #Compile each of the project folders (Only one of them may contain main, so the rest must be libraries)
  88. for FOLDER in "${FOLDER_ARRAY[@]}"; do
  89. echo "Compiling ${FOLDER} using ${COMPILER_FLAGS}."
  90. compileFolder "${FOLDER}"
  91. if [ $? -ne 0 ]
  92. then
  93. exit 1
  94. fi
  95. done
  96. # Assembling static library
  97. echo "Assembling object files into ${LIBRARY_NAME}.a."
  98. ar rcs ${LIBRARY_FILENAME} ${TARGET}/*${OBJECT_POSTFIX}
  99. # Cleaning up temporary objects
  100. echo "Cleaning up temporary ${LIBRARY_NAME} object files."
  101. rm -f ${TARGET}/*${OBJECT_POSTFIX}
  102. fi
  103. if [ ${BUILD_METHOD} = LAZY ]
  104. then
  105. # Save new checksum to file when done compiling
  106. echo ${NEW_SUM} > ${SUM_FILENAME}
  107. fi