From fcc08f8b7ebdbf15c569b8e89db63ccee8c5e281 Mon Sep 17 00:00:00 2001 From: Giovanni Bussi <bussi@MBP-30680.homenet.telecomitalia.it> Date: Sun, 13 May 2018 17:21:27 +0200 Subject: [PATCH] Allow direct #include from other modules I allowed include commands such as #include "../module/file.h", only in the case where module is an used module (or the current module). Later I would like to see if it is possible to eliminate the "make links" stuff completely. --- src/maketools/make.module | 4 +++ src/maketools/plumedcheck | 54 +++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/maketools/make.module b/src/maketools/make.module index 6e846e049..22826817e 100644 --- a/src/maketools/make.module +++ b/src/maketools/make.module @@ -90,6 +90,10 @@ codecheck: astyle: cd ../ ; ./astyle.sh $(CURDIR) +.PHONY: show_used_modules +show_used_modules: + @echo used_modules $(USE) + # generic makefile rules diff --git a/src/maketools/plumedcheck b/src/maketools/plumedcheck index d8f5cb44c..97a068c86 100755 --- a/src/maketools/plumedcheck +++ b/src/maketools/plumedcheck @@ -143,6 +143,10 @@ BEGIN{ core_modules["tools"]=1 core_modules["reference"]=1 +# declare these as empty arrays + used_modules[0]=1 + delete used_modules + # create tmp dir for future usage "mktemp -dt plumed.XXXXXX" | getline tmpdir @@ -164,6 +168,12 @@ BEGINFILE{ # found_include_system_header=0 # report_include_system_headers=0 +# guess type of file from extension + filetype="" + if(match(FILENAME,".*\\.h")) filetype="header" + if(match(FILENAME,".*\\.cpp")) filetype="source" + if(match(FILENAME,".*\\.ac")) filetype="autoconf" + # guess module name from directory # only works when path is specified filename=FILENAME @@ -171,13 +181,15 @@ BEGINFILE{ gsub("^[.]/","",filename); if(!match(filename,".*/.*")) filename=ENVIRON["PWD"] "/" filename gsub("/+","/",filename); # fix multiple slashes + filepath=filename module="" nf=split(filename,ff,"/"); if(nf>1){ module=ff[nf-1]; if(!(module in module_type)){ - path=filename + path=filepath sub("/.*$","/module.type",path); +# detect module type if((getline < path > 0) ){ module_type[module]=$0 information("module_type","module " module " has type '" module_type[module] "'" ); @@ -188,17 +200,28 @@ BEGINFILE{ if(!(module_type[module] in allowed_module_types)) error("wrong_module_type","module " module " has a wrong module type '" module_type[module] "'"); } } +# detect used modules + if(filetype=="source" || filetype=="header") { + if(!(module in used_modules)){ + tempfile = tmpdir "/used_modules." module + path=filepath + sub("/[^/]*$","",path); +# an explicit cd is required since the command might be run from a different directory + system("cd " path "; make show_used_modules 2>/dev/null > " tempfile) + if(getline < tempfile >0 && $1=="used_modules") for(i=2;i<=NF;i++) used_modules[module][$i]=1 + system("rm " tempfile) + used_modules_here="" + if(isarray(used_modules[module])) { + for(mod in used_modules[module]) used_modules_here=used_modules_here " " mod + } + information("used_modules",module " uses:" used_modules_here) + } + } } file=ff[nf]; filebase=file; sub("\\..*","",filebase); -# guess type of file from extension - filetype="" - if(match(FILENAME,".*\\.h")) filetype="header" - if(match(FILENAME,".*\\.cpp")) filetype="source" - if(match(FILENAME,".*\\.ac")) filetype="autoconf" - # checks that are done only on some modules will be skipped if the module name is not known if((filetype=="source" || filetype=="header") && !module) information("missing_module_name","module name is not know, some check will be skipped"); @@ -246,13 +269,22 @@ BEGINFILE{ # detect copyright lines if($0=="/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") in_copyright=1; # check direct inclusion of headers that would bypass module dependencies + if(module && match($0,"^# *include +\\\"\\.\\.")) { + included_module_name=$0; + sub("^# *include +\\\"\\.\\./","",included_module_name); + sub("/.*$","",included_module_name); # DOC: :include_dots: -# DOC: It is considered an error to include a file using a path starting with `..`. -# DOC: The reason is that this would allow to include PLUMED modules that have not been -# DOC: explicitly declared in the Makefile (e.g. using `#include "../tools/Vector.h"`). +# DOC: It is considered an error to include a file using a path starting with `../dir`, +# DOC: where `dir` is not the name of a module explicitly declared as used in the Makefile. # DOC: This might result in undetected dependences between the modules, which means that # DOC: by enabling some set of modules one would result in a non-linkable library. - if(match($0,"^# *include +\\\"\\.\\.")) error("include_dots","cannot include files using .. path"); +# DOC: As an exception, one can include files such as `../dir` where `dir` is the current module +# DOC: since this would obviously create no problem. +# DOC: This would simplify life when moving files from a directory to another. + if(module != included_module_name) # ignore case where module is the same + if(!isarray(used_modules[module]) || (included_module_name in used_modules[module])==0) + error("include_dots","wrong include. Module '" included_module_name "' is not used."); + } # check if there is anything behind copyright and preprocessor commands if(!in_copyright && !match($0,"^# *include") && !match($0,"^# *ifndef") && !match($0,"^# *endif") && !match($0,"^# *define") && !match($0,"^ *$")) found_non_preprocessor_lines=1 -- GitLab