compile_code.py 37 KB

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