compile_code.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. #!/usr/bin/env python3
  2. import json
  3. import os
  4. import sys
  5. import random
  6. #####################
  7. # Variables to edit #
  8. #####################
  9. # commands options
  10. commandlist_complete = ["tests-128", "up-steg", "tests-256", "tests-dbg-128", "tests-dbg-256", "examples-256","parser-dbg" ,"parser", "parser-128", "parser-256", "libstatic-128", "libstatic-256", "libdynamic-128", "libdynamic-256", "swigpy-128" , "swigpy-256" ]
  11. if ( len(sys.argv) > 1 ):
  12. commandlist = sys.argv[1:]
  13. for command in commandlist :
  14. if (( command in commandlist_complete ) == False ):
  15. print ( "command " + command + " not in: " + str(commandlist_complete))
  16. exit()
  17. else:
  18. #commandlist = commandlist_complete # to compile everithing
  19. commandlist = ["libdynamic-256", "libdynamic-128", "parser"]
  20. #commandlist = ["tests-dbg-256"]
  21. #commandlist = ["tests-256"]
  22. #commandlist = ["examples-256"]
  23. #commandlist = ["swigpy-256", "swigpy-128"]
  24. production_code = 1
  25. platform = "gnu-linux" # alternatives: "gnu-linux" "windows"
  26. force_indentation = 1 # does not indent the original code
  27. enable_clang = 0 # enable clang code analysis
  28. enable_clang_tidy = 0 # enable clang-tidy code analysis
  29. enable_cppcheck = 0 # enable cppcheck code analysis
  30. skip_configuration_prompt = 1 # skip the post compilation program
  31. regenerate_shared_lib = 1 # regenerate shared library when command list contains "libdynamic-256", "libdynamic-128", "parser"
  32. #pythondir_inc = "/usr/include/python3.8/"
  33. cmd="python3 --version | sed 's/Python //' | tr '.' ' ' | awk '{print $1 \".\" $2 }' | sed 's/^/\/usr\/include\/python/' | sed 's/$/\//'"
  34. pythondir_inc = os.popen( cmd ).read()
  35. #######################
  36. # Do not modify below #
  37. #######################
  38. if (( len(sys.argv) == 1 ) and ( production_code == 1 )):
  39. force_indentation = 0
  40. enable_clang = 0
  41. enable_clang_tidy = 0
  42. enable_cppcheck = 0
  43. skip_configuration_prompt = 0
  44. regenerate_shared_lib = 1
  45. commandlist = ["up-steg", "libdynamic-256", "libdynamic-128", "libstatic-256", "libstatic-128", "parser", "swigpy-128", "swigpy-256" ]
  46. #############################
  47. # Copy and extract function #
  48. #############################
  49. def mkdir_cp_exctract_lib_addcppheader( directory_str ) :
  50. # copy code in the cache directory
  51. dst_dir = project_dir + directory_str
  52. cmd = "mkdir " + dst_dir + " ; cp -r " + original_code_dir + " " + dst_dir
  53. os.system( cmd )
  54. # add visibility attributes to backend headers
  55. cmd = "du -a " + dst_dir + " | cut -f 2 | grep _backend | grep '\.h' | xargs -I + sh -c \"./backend/add_visibility_attributes.sh + +.bkp ; rm + ; mv +.bkp + ;\""
  56. os.system( cmd )
  57. # extract header files from documentation
  58. cmd = "du -a " + dst_dir + " | cut -f 2 | awk '/\.md/ {print $0}' | xargs -I + sh -c \"./backend/doc2lib.sh + ; \""
  59. os.system( cmd )
  60. # add cpp headers
  61. cmd = "du -a " + dst_dir + " | cut -f 2 | awk '/\.h/{print $0}' | xargs -I + sh -c \"cat ../archives/resources/miscellaneus/cpp/head.txt + ../archives/resources/miscellaneus/cpp/tail.txt > +.bkp ; rm + ; mv +.bkp + ;\""
  62. os.system( cmd )
  63. ############################
  64. # Dump compilation command #
  65. ############################
  66. def dump_compilation ( compiler, outputtype, targetname, all_flags, codeconf_flags, all_files, flatdumpdir, first_stage ) :
  67. cppchecksuppressions = " --suppress=uninitStructMember:test_io_crypto.c --suppress=objectIndex "
  68. all_file_str = str(all_files).replace('\'','').replace('[','').replace(']','').replace(',','')
  69. if ( outputtype == "debug" ):
  70. compilation_str = compiler + str(all_flags) + " -g -O0 -fno-omit-frame-pointer " + all_file_str + " -o " + targetname + " 2>gcc_"+targetname+".log ; "
  71. if ( outputtype == "debug-dynamic-lib" ):
  72. compilation_str = compiler + str(all_flags) + " -g -O0 -fno-omit-frame-pointer " + all_file_str + " -ldl -o " + targetname + " 2>gcc_"+targetname+".log ; "
  73. elif ( outputtype == "executable" ):
  74. compilation_str = compiler + str(all_flags) + " -O3 " + all_file_str + " -o " + targetname + " 2>gcc_"+targetname+".log ; "
  75. elif ( outputtype == "executable-dynamic-lib" ):
  76. compilation_str = compiler + str(all_flags) + " -O3 " + all_file_str + " -ldl -o " + targetname + " 2>gcc_"+targetname+".log ; "
  77. elif ( outputtype == "libdynamic" ) :
  78. compilation_str = compiler + str(all_flags) + " -O3 -fPIC -shared -o " + targetname + " " + all_file_str + " 2>gcc_"+targetname+".log ; "
  79. elif ( outputtype == "libstatic" ):
  80. compilation_str = compiler + str(all_flags) + " -O3 -fPIC -c " + all_file_str + " 2>gcc_"+targetname+".log ; ar rc -o " + targetname + " " + flatdumpdir + "/*.o ; "
  81. elif (( outputtype == "swigpy-128" ) or ( outputtype == "swigpy-256" )) :
  82. compilation_str = compiler + str(all_flags) + " -O3 -fPIC -shared -o " + targetname + " " + all_file_str + " -I " + pythondir_inc + " 2>gcc_"+targetname+".log ; "
  83. if ((( outputtype == "libdynamic" ) or ( outputtype == "libstatic" ) or ( outputtype == "debug" ) or ( outputtype == "debug-dynamic-lib" ) or ( outputtype == "executable" ) or ( outputtype == "executable-dynamic-lib" )) and ( first_stage == 0 )):
  84. if ( enable_clang == 1 ) :
  85. compilation_str = compilation_str + " clang --analyze " + str(all_flags) + " ./*.c ./*.h 2>clang_"+targetname+".log ; "
  86. if ( enable_cppcheck == 1 ) :
  87. compilation_str = compilation_str + " cppcheck " + str(codeconf_flags) + cppchecksuppressions + " ./*.c ./*.h 1>cppcheck_stdout_"+targetname+".log 2>cppcheck_stderr_"+targetname+".log ; "
  88. if ( enable_clang_tidy == 1 ) :
  89. compilation_str = compilation_str + " clang-tidy ./*.c -- " + str(codeconf_flags) + " 1>clang_tidy_"+targetname+".log 2>clang_tidy_summary_" +targetname + ".log ; "
  90. with open( flatdumpdir + "/compile_"+targetname+".sh", 'w') as file:
  91. file.write(compilation_str)
  92. file.close()
  93. os.system("chmod 777 " + flatdumpdir + "/compile_"+targetname+".sh")
  94. ########################
  95. # Compilation routine ##
  96. ########################
  97. def compile ( platform, targetname, outputtype, codeconf_flags, filelists ) :
  98. cachedirrel = "/cache/" + targetname
  99. builddir = project_dir +"/build"
  100. mkdir_cp_exctract_lib_addcppheader( cachedirrel )
  101. cachedirabs = project_dir + cachedirrel
  102. # configure flags
  103. if platform == "gnu-linux" :
  104. all_flags = " -D XRN_GNU_LINUX=1 " + code_cstd_flags + code_cleaner_flags + code_pthread_flags + stack_protection_flags + fortify_source_flags + warnings_flags + git_flags + codeconf_flags
  105. compiler = " gcc "
  106. else :
  107. all_flags = " -D XRN_GNU_LINUX=0 " + windows_flags + windows_end_flags + code_cstd_flags + code_cleaner_flags + code_pthread_flags + stack_protection_flags + fortify_source_flags + warnings_flags + git_flags + codeconf_flags
  108. compiler = " x86_64-w64-mingw32-gcc "
  109. # configure swig files
  110. if ( outputtype == "swigpy-128" ):
  111. cmd = "du -a " + cachedirabs + " | cut -f 2 | awk ' /\.i/ {print $0}' | grep python | xargs -I + sh -c \"./backend/create_interface_python.sh + " + builddir + "/py 128; \""
  112. os.system(cmd)
  113. elif ( outputtype == "swigpy-256" ):
  114. cmd = "du -a " + cachedirabs + " | cut -f 2 | awk ' /\.i/ {print $0}' | grep python | xargs -I + sh -c \"./backend/create_interface_python.sh + " + builddir + "/py 256; \""
  115. os.system(cmd)
  116. if ( targetname == "xrnconf" ):
  117. first_stage = 1
  118. else :
  119. first_stage = 0
  120. # configure files
  121. flatdumpdir = cachedirabs + "/flatdump"
  122. all_files = []
  123. all_files_flat = []
  124. for filelist in filelists:
  125. for file in filelists_json[filelist]:
  126. if os.path.exists( cachedirabs + "/" + file ) == True :
  127. all_files.append( cachedirabs + "/" + file )
  128. all_files_flat.append( os.path.basename(file) )
  129. # do a flat dump of all the source files
  130. os.system( "mkdir " + flatdumpdir )
  131. for file in all_files:
  132. os.system("cp " + file + " " + flatdumpdir )
  133. # if the run configuration has been run (include those files in the compilation
  134. if ( os.path.exists( project_dir + "/cache/headers" )) :
  135. all_files_flat.append( "default_permutation_settings.h" )
  136. all_files_flat.append( "default_encoding_settings.h" )
  137. os.system( "cp " + project_dir + "/cache/headers/* " + flatdumpdir )
  138. # dump compilation commands
  139. dump_compilation ( compiler, outputtype, targetname, all_flags, codeconf_flags, all_files_flat, flatdumpdir, first_stage )
  140. corerefdir = builddir + "/coderef/" + targetname
  141. cmd = "mkdir " + corerefdir + "; cp -r " + flatdumpdir + " " + corerefdir
  142. os.system( cmd )
  143. print("compile " + targetname )
  144. os.system("cd " + flatdumpdir + ";" + " ./compile_"+targetname+".sh ")
  145. # copy the results in the build directory
  146. if (( outputtype == "executable" ) or ( outputtype == "executable-dynamic-lib" ) or ( outputtype == "debug" )or ( outputtype == "debug-dynamic-lib" )):
  147. os.system("cp " + flatdumpdir + "/" +targetname + " " + project_dir + "/build/bin/")
  148. os.system("chmod 777 " + project_dir + "/build/bin/" +targetname )
  149. elif (( outputtype == "libdynamic" ) or ( outputtype == "libstatic" )) :
  150. os.system("cp " + flatdumpdir + "/" +targetname + " " + project_dir + "/build/sharedlib/")
  151. elif (( outputtype == "swigpy-128" ) or ( outputtype == "swigpy-256" )) :
  152. os.system("cp " + flatdumpdir + "/" +targetname + " " + project_dir + "/build/py/")
  153. os.system("cp " + flatdumpdir + "/gcc_" +targetname + ".log " + project_dir + "/build/reports/compilationlogs ")
  154. outcmd = os.popen("cat " + flatdumpdir + "/gcc_" + targetname + ".log " ).read()
  155. print("################## gcc stderr ##################")
  156. print(outcmd)
  157. if ( first_stage == 0 ) :
  158. if ( enable_clang == 1 ) :
  159. os.system("cp " + flatdumpdir + "/clang_" +targetname + ".log " + project_dir + "/build/reports/compilationlogs")
  160. if ( enable_clang_tidy == 1 ) :
  161. os.system("cp " + flatdumpdir + "/clang_tidy_" +targetname + ".log " + project_dir + "/build/reports/compilationlogs")
  162. if ( enable_cppcheck == 1 ) :
  163. os.system("cp " + flatdumpdir + "/cppcheck_stdout_" +targetname + ".log " + project_dir + "/build/reports/compilationlogs")
  164. os.system("cp " + flatdumpdir + "/cppcheck_stderr_" +targetname + ".log " + project_dir + "/build/reports/compilationlogs")
  165. if (( enable_clang == 1 ) and (targetname != "xrnconf")) :
  166. outcmd = os.popen("cat " + flatdumpdir + "/clang_" + targetname + ".log " ).read()
  167. print("################# clang stderr #################")
  168. print(outcmd)
  169. if (( enable_clang_tidy == 1 ) and (targetname != "xrnconf")) :
  170. outcmd = os.popen("cat " + flatdumpdir + "/clang_tidy_" + targetname + ".log " ).read()
  171. print("############### clang-tidy stderr ###############")
  172. print(outcmd)
  173. if (( enable_cppcheck == 1 ) and (targetname != "xrnconf")) :
  174. outcmd = os.popen("cat " + flatdumpdir + "/cppcheck_stderr_" + targetname + ".log " ).read()
  175. print("############### cppcheck stderr ################")
  176. print(outcmd)
  177. # get project directory
  178. script_dir = os.popen("pwd").read().replace("\n", "")
  179. project_dir = os.path.dirname(script_dir)
  180. original_code_dir = project_dir + "/code"
  181. reports_dir = project_dir + "/build/reports"
  182. # remove and recreate directories
  183. if regenerate_shared_lib == 1 :
  184. cmd = "rm -rf ../build ../cache; mkdir ../build ../build/coderef ../build/reports ../build/reports/compilationlogs ../build/py ../build/sharedlib ../build/bin ../build/doc ../build/doc/pdf ../build/doc/html ../build/doc/html/svg ../cache "
  185. else :
  186. if (( os.path.isfile( "../build/sharedlib/xrnlib-128.so" ) == False ) or \
  187. ( os.path.isfile( "../build/sharedlib/xrnlib-128.so" ) == False )):
  188. print("shared libraries need to be generate if regenerate_shared_lib == 0 ")
  189. exit(-1)
  190. cmd = ""
  191. if os.path.exists( "../build" ) == False :
  192. cmd = "mkdir ../build ; "
  193. cmd = cmd + "rm -rf ../build/bin ../build/coderef ../build/doc ../build/py ../build/reports ../cache; mkdir ../build/coderef ../build/reports ../build/reports/compilationlogs ../build/py ../build/bin ../build/doc ../build/doc/pdf ../build/doc/html ../build/doc/html/svg ../cache "
  194. os.system( cmd )
  195. # decide output setting files
  196. permutation_header_file="default_permutation_settings.h"
  197. encoder_header_file="default_encoding_settings.h"
  198. # read the file list
  199. with open('./backend/filelist.json', 'r') as file:
  200. jsondata = file.read()
  201. filelists_json = json.loads( jsondata )
  202. # define windows flags
  203. windows_flags = " -Wl,--stack -Wl,8454272 "
  204. windows_compiler = " x86_64-w64-mingw32-gcc "
  205. windows_end_flags = " -lbcrypt "
  206. # get git variables
  207. git_version = os.popen("git rev-list --count HEAD").read().replace("\n", "")
  208. git_dirty_flags = os.popen("git describe --dirty --always --tags | awk '{if (/dirty/){ print 1} else {print 0}}'").read().replace("\n", "")
  209. git_version_str = os.popen("git describe --dirty --always --tags").read().replace("\n", "")
  210. # define compilation option
  211. #code_cstd_flags = " -ansi -pedantic " # use the c89 flags
  212. #code_cstd_flags = " -std=c11 " # use the c11 flags
  213. code_cstd_flags = " "
  214. code_cleaner_flags = " -fdata-sections -ffunction-sections -Wl,--gc-sections " # optimize out not used functions (printing debugging ect)
  215. #code_optimization_flags = " -O3 " # maximum level of optimization
  216. code_pthread_flags = " -pthread " # compile with threads
  217. stack_protection_flags = " -fstack-protector-all " # add stack protection to all the functions (performance penalty)
  218. fortify_source_flags = " -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 " # add compiler checks for buffer overflows
  219. warnings_flags = " -Wall -Wconversion -Wformat -Wformat-security -Wnonnull " # add wornings during compilation
  220. git_flags = " -D GIT_VERSION="+ git_version + " -D XRN_GIT_VERSION_STR="+ "\""+git_version_str+"\""+ " -D XRN_GIT_DIRTY_FLAG="+ "\\\"" + git_dirty_flags+ "\\\" "
  221. codeconf_flags = " -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 " # code configuration flags
  222. #######################
  223. # perform code checks #
  224. #######################
  225. # check errors codes
  226. cmd = "du " + project_dir + " -a | cut -f 2 | grep '\/lib\/' | grep '\.c' | xargs cat | grep -v '\/\/' | grep XPRINT_ERR | awk '// { print $2 }' | tr -d ',' "
  227. outcmd = os.popen(cmd).read().split("\n")[:-1]
  228. outcmdint = [int(i) for i in outcmd]
  229. available_codes = []
  230. error_in_codes = 0
  231. error_code = 0
  232. for i in range(0, len(outcmdint)):
  233. for j in range(i+1, len(outcmdint)):
  234. if ( outcmdint[i] == outcmdint[j] ):
  235. error_in_codes = 1
  236. error_code = outcmdint[i]
  237. seen = 0
  238. for j in range(0, len(outcmdint)):
  239. if ( outcmdint[j] == i ):
  240. seen = 1
  241. if ( seen == 0 ):
  242. if ( production_code == 0 ) :
  243. available_codes = available_codes + [i]
  244. if ( production_code == 0 ) :
  245. available_codes = available_codes + [len(outcmdint)+1]
  246. if production_code == 0 :
  247. print("available error codes: " + str(available_codes))
  248. if error_in_codes == 1 :
  249. print("error in the error codes: " + str( error_code ))
  250. exit(0)
  251. #check for TODO HANDLER and CHECK comments in source files
  252. keywords = ["TODO","HANDLER","CHECK"]
  253. for keyword in keywords :
  254. cmd = "grep -Rl '\/\/.*"+keyword+"' " + original_code_dir
  255. outcmd = os.popen(cmd).read()
  256. if ( outcmd.isupper() or outcmd.islower()) :
  257. print("\nfiles with "+keyword+"s comments")
  258. print( os.popen(cmd).read())
  259. #check for not safe functions and suggest replacements
  260. keywords = ["strcpy", "strcat", "gets", "sprintf", "strlen" , "strcmp" , "atoi", "atol", "atoll", "atof" , "free"]
  261. replacements = ["snprintf", "strncat", "fgets", "snprintf", "strnlen", "strncmp", "strtol", "strtol", "strtoll", "strtof", "XRN_FREE"]
  262. for i in range(0, len(keywords)):
  263. keyword = keywords[i]
  264. replacement = replacements[i]
  265. if ( keyword == "free" ): # only for the library
  266. cmd = "grep -Rl '"+keyword+"(' " + original_code_dir + " | grep -v app | grep -v xrn_common_backend | grep -v python "
  267. outcmd = os.popen(cmd).read()
  268. else :
  269. cmd = "grep -Rl '\/\/.*"+keyword+"' " + original_code_dir + " | grep -v examples | grep -v tests "
  270. outcmd = os.popen(cmd).read()
  271. if ( outcmd.isupper() or outcmd.islower()) :
  272. print("\nfiles with "+keyword+"() function detected, cosider " + replacement + "() as replacement")
  273. print( os.popen(cmd).read())
  274. #check if line continuation in comments
  275. cmd = "du -a " + project_dir + " | cut -f 2 | awk '/\.c/ || /\.h/ || /\.cpp/ {print $0}' | xargs -I + sh -c \"cat + | awk '/\/\/.*\\\\\\\\$/ {print \$0}'\""
  276. outcmd = os.popen(cmd).read()
  277. if ( outcmd.isupper() or outcmd.islower()) :
  278. print("found wrong comment termination: " + outcmd)
  279. exit()
  280. ########################
  281. # change original code #
  282. ########################
  283. # indent code
  284. if ( force_indentation == 1 ) :
  285. # do it twice to avoid oscillations in files due to the indentation
  286. for i in range(2) :
  287. indentcmd = " indent "
  288. indentopt = " -kr -l110 -lc110 -bad -bbb -br -bli1 -ce -cli4 -saf -sai -saw -prs -sbi4 -nut -bfde "
  289. cmd = "du -a " + original_code_dir + " | cut -f 2 | awk '/\.c/ || /\.h/ || /\.cpp/ {print $0}' | grep -v 'xrn_lib_interposer_dll.h' | grep -v 'xrn_lib_interposer.h' | grep -v 'xrnlib.h' | grep -v 'steg_data.h' | xargs -I + sh -c \"" + indentcmd + " + " + indentopt + " \";\n"
  290. cmd = cmd + "du -a " + original_code_dir + " | cut -f 2 | awk '/\.c~/ || /\.h~/ || /\.cpp~/ {print $0}' | xargs -I + sh -c 'rm -fr +';\n"
  291. cmd = cmd + "du -a " + original_code_dir + " | cut -f 2 | awk '/\.c/ || /\.h/ || /\.cpp/ {print $0}' | grep -v 'xrn_lib_interposer_dll.h' | grep -v 'xrn_lib_interposer.h' | grep -v 'xrnlib.h' | grep -v 'steg_data.h' | xargs -I + sh -c \"./backend/remove_double_lines.sh + > +.bkp ; rm + ; mv +.bkp + \""
  292. os.system( cmd )
  293. # add license
  294. cmd = "grep -rL \"Software License\" " + original_code_dir + " | awk '/\.c/ || /\.h/ || /\.cpp/ {print $0}' | grep -v 'xrn_lib_interposer_dll.h' | grep -v 'xrn_lib_interposer.h' | grep -v 'xrnlib.h' | xargs -I + sh -c \"cat ../archives/resources/miscellaneus/license.txt + > +.bkp ; rm + ; mv +.bkp + \" ; "
  295. os.system( cmd )
  296. #############################################
  297. # check what operation need to be performed #
  298. #############################################
  299. # done to skip the first compilation stage if only documents need to be compiled
  300. first_stage_compilation = 0
  301. parser_with_lexer = 0
  302. for command in commandlist :
  303. if (( command == "tests-128" ) or ( command == "tests-256" ) or \
  304. ( command == "tests-dbg-128" ) or ( command == "tests-dbg-256" ) or \
  305. ( command == "examples-256" ) or \
  306. ( command == "parser-128" ) or ( command == "parser-256" ) or \
  307. ( command == "swigpy-128" ) or ( command == "swigpy-256" ) or \
  308. ( command == "libstatic-128" ) or ( command == "libstatic-256" ) or \
  309. (( command == "libdynamic-128" ) and regenerate_shared_lib ) or \
  310. (( command == "libdynamic-256" ) and regenerate_shared_lib ) \
  311. ):
  312. first_stage_compilation = 1
  313. if ( command == "parser" ) :
  314. parser_with_lexer = 1
  315. #########################################
  316. # perform lexer and autocomplete checks #
  317. #########################################
  318. if (( parser_with_lexer == 1 ) and ( production_code == 0)):
  319. # check lexcheck.h
  320. cmd = "cd ./backend/lexer ; ./check_lexcheck.sh"
  321. errors = os.popen( cmd ).read()
  322. if ( errors != "" ) :
  323. print("error in lexcheck.h\n")
  324. print("trace " + errors + "\n")
  325. exit()
  326. # autogenerate xrnlib-cli-autocomplete.sh
  327. cmd = "cd ./backend ; ./generate_autocomplete.sh " + "../../cache/autocomplete_tmp.sh 2>/dev/null ; diff ../../cache/autocomplete_tmp.sh ./xrnlib-cli-autocomplete.sh "
  328. errors = os.popen( cmd ).read()
  329. if ( errors != "" ) :
  330. print("autocomplete out of date\ncommand run: " + cmd + "\nto fix it run\n./install.sh; source ./source.sh; cd backend; ./generate_autocomplete.sh; cd .. ;")
  331. print("remember to push changes into repo")
  332. if os.path.exists( "../cache/autocomplete_tmp.sh" ) == True :
  333. os.system("rm ../cache/autocomplete_tmp.sh")
  334. ###################################
  335. # perform lexer and parser checks #
  336. ###################################
  337. if ( parser_with_lexer == 1 ) :
  338. cmd = "cd ./backend/lexer ; ./parser_options_functions_check.sh"
  339. errors = os.popen( cmd ).read()
  340. if ( "correct" not in errors ) :
  341. print("error in parser_options.h or parser_functions.h\n")
  342. print("inconsistent options/functions compared to lexcheck.h\n")
  343. print(errors)
  344. exit()
  345. #######################################
  346. # perform the first stage compilation #
  347. #######################################
  348. if ( first_stage_compilation == 1 ) :
  349. targetname = "xrnconf"
  350. codeconf_flags = " -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=1 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  351. if ( skip_configuration_prompt == 1 ) :
  352. codeconf_flags = codeconf_flags + " -D XRN_SKIP_CONFIGURATION_PROMPT=1 "
  353. else :
  354. codeconf_flags = codeconf_flags + " -D XRN_SKIP_CONFIGURATION_PROMPT=0 "
  355. filelists = ["libh" ,"libc" ,"confgenh" ,"confgenc" , "mainc", "main_xconfig_ch" ]
  356. outputtype = "executable"
  357. compile ( platform, targetname, outputtype, codeconf_flags, filelists )
  358. # compile
  359. cacheheaders = project_dir + "/cache/headers"
  360. permutation_header_file_path = cacheheaders+"/"+permutation_header_file
  361. encoder_header_file_path = cacheheaders+"/"+encoder_header_file
  362. os.system( "rm -rf " + project_dir + "/cache/* ; mkdir " + cacheheaders + " ; " + project_dir + "/build/bin/"+targetname + " " + permutation_header_file_path + " " + encoder_header_file_path )
  363. # check if it produced outputs
  364. if ( os.path.exists(permutation_header_file_path) and os.path.exists( encoder_header_file_path )):
  365. if ( os.path.getsize(permutation_header_file_path) <= 0 ) or ( os.path.getsize(encoder_header_file_path) <= 0 ) :
  366. exit()
  367. elif (( commandlist[0] != "examples-256" ) and ( skip_configuration_prompt == 1 )):
  368. ###############################
  369. # check if swig is up to date #
  370. ###############################
  371. flatdumpdir = project_dir + "/build/coderef/" + targetname + "/flatdump"
  372. # check swig compatibility
  373. swigheaderfile = flatdumpdir + "/swigheader.h"
  374. # regenerate the swigpy header
  375. cmd = "cat " + permutation_header_file_path + " "
  376. cmd = cmd + encoder_header_file_path + " "
  377. cmd = cmd + flatdumpdir + "/xrn_settings.h "
  378. cmd = cmd + flatdumpdir + "/xrn_common.h "
  379. cmd = cmd + flatdumpdir + "/xrn_arithmetic.h "
  380. cmd = cmd + flatdumpdir + "/xrn_encoder.h "
  381. cmd = cmd + flatdumpdir + "/xrn_core.h "
  382. cmd = cmd + flatdumpdir + "/xrn_miners.h "
  383. cmd = cmd + flatdumpdir + "/xrn_crypto.h "
  384. cmd = cmd + " > " + swigheaderfile
  385. os.system(cmd)
  386. cmd = "diff -E -Z -b -w -B " + swigheaderfile + " " + "../" + filelists_json['swigpyh'][0]
  387. errors = os.popen( cmd ).read()
  388. if ( errors != "" ) :
  389. print("../" + filelists_json['swigpyh'][0] + " out of date")
  390. print(errors)
  391. print("to fix the issue, you can run:\n./compile_code.py examples-256; cd backend; ./create_header_python_interface.sh ; cd .. ")
  392. exit(-1)
  393. else :
  394. cmd = "rm " + swigheaderfile
  395. else :
  396. exit()
  397. #############################
  398. # perform interposer checks #
  399. #############################
  400. def check_interposer ( targetname ):
  401. if (( parser_with_lexer == 1 ) and ( commandlist[0] != "examples-256" )) :
  402. flatdump_path = "../../build/coderef/" + targetname +"/flatdump/"
  403. # autogenerate interposer headers
  404. cmd = "cd ./backend ; python3 autogen_interposer.py ../../cache/xrn_lib_interposer.h ../../cache/xrn_lib_interposer_dll.h " + flatdump_path + " ;"
  405. os.system( cmd )
  406. cmd0 = "diff ../cache/xrn_lib_interposer.h ../code/lib/xrn_interfaces/c/inc/xrn_lib_interposer.h "
  407. errors1 = os.popen( cmd0 ).read()
  408. cmd1 = "diff ../cache/xrn_lib_interposer_dll.h ../code/app/parser/inc/xrn_lib_interposer_dll.h "
  409. errors2 = os.popen( cmd1 ).read()
  410. if (( errors1 != "" ) or ( errors2 != "" )):
  411. print("interposer headers out of date\ncommand run: " + cmd0 + "\ncommand run: " + cmd1 + "\nto fix it run\n./compile_code.py examples-256 ; cd backend; python3 autogen_interposer.py; cd .. ;")
  412. print("remember to push changes into repo")
  413. #if os.path.exists( "../cache/xrn_lib_interposer.h" ) == True :
  414. # os.system("rm ../cache/xrn_lib_interposer.h")
  415. #if os.path.exists( "../cache/xrn_lib_interposer_dll.h" ) == True :
  416. # os.system("rm ../cache/xrn_lib_interposer_dll.h")
  417. ##########################
  418. # generate configuration #
  419. ##########################
  420. interposer_check_done = 0
  421. for command in commandlist :
  422. perform_final_compilation = 1
  423. if ( command == "up-steg" ) :
  424. perform_final_compilation = 0
  425. os.system("cd backend; ./compile_upper_steganography.sh")
  426. elif ( command == "tests-dbg-128" ) :
  427. targetname = "tests-dbg-128"
  428. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=1 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=128 -D XRN_DEBUG=1 "
  429. filelists = ["libh" ,"libc" ,"libc-dev" ,"testc" ,"testh" , "mainc", "main_tests_ch" ]
  430. outputtype = "debug"
  431. elif ( command == "tests-dbg-256" ) :
  432. targetname = "tests-dbg-256"
  433. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=1 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 -D XRN_DEBUG=1 "
  434. filelists = ["libh" ,"libc" ,"libc-dev" ,"testc" ,"testh" , "mainc", "main_tests_ch" ]
  435. outputtype = "debug"
  436. elif ( command == "tests-128" ) :
  437. targetname = "tests-128"
  438. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=1 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=128 "
  439. filelists = ["libh" ,"libc" ,"libc-dev" ,"testc" ,"testh" , "mainc", "main_tests_ch" ]
  440. outputtype = "executable"
  441. elif ( command == "tests-256" ) :
  442. targetname = "tests-256"
  443. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=1 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  444. filelists = ["libh" ,"libc" ,"libc-dev" ,"testc" ,"testh" , "mainc", "main_tests_ch" ]
  445. outputtype = "executable"
  446. elif ( command == "examples-256" ) :
  447. targetname = "examples-256"
  448. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=1 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  449. filelists = ["libh" ,"libc" ,"libc-dev" ,"examplesc" ,"examplesh" , "mainc", "main_examples_ch" ]
  450. outputtype = "executable"
  451. elif ( command == "parser-128" ) :
  452. targetname = "xrnlib-128-cli"
  453. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=1 -D XNBITS=128 "
  454. filelists = ["libh" ,"libc" ,"parserc" ,"parserh" , "lexerc", "lexerh", "mainc", "main_parser_ch" ]
  455. outputtype = "executable"
  456. elif ( command == "parser-256" ) :
  457. targetname = "xrnlib-256-cli"
  458. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=1 -D XNBITS=256 "
  459. filelists = ["libh" ,"libc" ,"parserc" ,"parserh" , "lexerc", "lexerh", "mainc", "main_parser_ch" ]
  460. outputtype = "executable"
  461. elif ( command == "parser" ) :
  462. targetname = "xrnlib-cli"
  463. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=0 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=1 -D XNBITS=256 "
  464. filelists = [ "parserc" ,"parserh" , "lexerc", "lexerh", "mainc", "main_parser_ch" ]
  465. outputtype = "executable-dynamic-lib"
  466. elif ( command == "parser-dbg" ) :
  467. targetname = "xrnlib-cli"
  468. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=0 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=0 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=1 -D XNBITS=256 "
  469. filelists = [ "parserc" ,"parserh" , "lexerc", "lexerh", "mainc", "main_parser_ch" ]
  470. outputtype = "debug-dynamic-lib"
  471. elif ( command == "libstatic-128" ) :
  472. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=128 "
  473. outputtype = "libstatic"
  474. targetname = "xrnlib-128.a"
  475. filelists = ["libh" ,"libc", "libc-dev"]
  476. elif ( command == "libstatic-256" ) :
  477. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  478. outputtype = "libstatic"
  479. targetname = "xrnlib-256.a"
  480. filelists = ["libh" ,"libc", "libc-dev"]
  481. elif (( command == "libdynamic-128" ) and regenerate_shared_lib ) :
  482. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=128 "
  483. filelists = ["libh" ,"libc","libc-dev"]
  484. targetname = "xrnlib-128.so"
  485. outputtype = "libdynamic"
  486. elif (( command == "libdynamic-256" ) and regenerate_shared_lib ) :
  487. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=0 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  488. outputtype = "libdynamic"
  489. filelists = ["libh" ,"libc","libc-dev"]
  490. targetname = "xrnlib-256.so"
  491. elif ( command == "swigpy-128" ) :
  492. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=1 -D XCOMPILEPARSER=0 -D XNBITS=128 "
  493. outputtype = "swigpy-128"
  494. targetname = "_xrnlib128.so"
  495. filelists = ["libh" ,"libc" ,"libc-dev" ,"swigpyc128", "swigpyh" ]
  496. elif ( command == "swigpy-256" ) :
  497. codeconf_flags = " -D XRN_MONOLITIC_EXECUTABLE=1 -D XCOMPILELEXERONLY=0 -D XCOMPILEEXAMPLES=0 -D XCOMPILETESTS=0 -D XRUNCONFGEN=0 -D XSKIPMAIN=1 -D SWIGPYTHONEN=1 -D XCOMPILEPARSER=0 -D XNBITS=256 "
  498. outputtype = "swigpy-256"
  499. targetname = "_xrnlib256.so"
  500. filelists = ["libh" ,"libc" ,"libc-dev" ,"swigpyc256", "swigpyh" ]
  501. else :
  502. continue
  503. if ( perform_final_compilation == 1 ) :
  504. compile ( platform, targetname, outputtype, codeconf_flags, filelists )
  505. if ( interposer_check_done == 0 ) :
  506. check_interposer ( targetname )
  507. interposer_check_done = 1
  508. #clean cache directory
  509. # os.system( "rm -rf " + project_dir + "/cache/* ")