Inhalt
Topic:.CheckDeps_C.
Topic:.CheckDeps_C.problem.
Maker checks older/newer file. If older versions are used, no sensitive. Unix: copy produces newer file - resolve problems.
Maker syntax to complex (writeonly script)
Dependencies from all headers?
Building of Dependencies with a Compiler tool needs some time.
Topic:.CheckDeps_C.solution.
The tool CheckDeps_C evaluates C/C++-language files to check its timestamps and dependencies. It is written in Java: package srcJava_Zbnf/org/vishia/checkDeps_C/package-summary. It is able to call as command line invocation from Windows batch-files or a Unix shell script or it is able to call especially in a script of Zmake.
Topic:.CheckDeps_C.deps.
Last changed: 2012-01
The tool srcJava_Zbnf/org/vishia/checkDeps_C/CheckDependencyFile reads an input text file which contains from the last calling:
all source files inclusively its header files with its time stamp
all dependencies of each file
If such a list is not available because it is the first build or a build all invocation, the list can be missed. Then no timestamps and dependencies are known.
One after the another source file are processed with this class.
Either the time stamp of the source file is exact the same. Then the source file should be assumed as unchanged. In this case all of its primary dependencies are unchanged and known from this block in the dependency file. But the dependent files should be testet too. It is recursively.
Or the time stamp is changed, older or newer, then the source file may be changed. In this case all of its dependencies are invalid.
If the dependencies are invalid, the file is checked line per line. Each found #include
statement is a dependency for the source file. All depending files are checked in the same way like the source file. It means,
a dependency-file may be unchanged because its time stamp is unchanged. Then the known dependencies are used as known for
the deeper level and they are checked, but the unchanged file is not processed.
The result of the dependency check is the new dependency situation, which are logged into the dependency file written as output.
If a file is changed or any of its dependency files are changed, the file should be translated (compiled) newly. If any headerfile is changed, but the source file is not changed, the source file should be translated anyway too. To force the translation, its object file or more files are deleted from the object directory.
The deleting of the object file(s) should be done immediately while the inconsitency was found. Because a next processing of the dependency and time-stamp check with the newly written dependency file would not found a changed file. Anytime the comparison between the last and the current situation will be assessed.
A standard maker (GNU, ANT) or a check of existence of the objectfile (in a shell or batch script) will be force the compilation because the object file is removed. If the object file was not removed and the source will be changed but older or any dependency is unkown in the maker script, the maker will not force the compilation. That will be faulty. The deleting of the object helps to educate the correct situation.
Topic:.CheckDeps_C.Zmake.
Last changed: 2017-08
Usual the dependency checker is used in a subroutine which is invoked with zmake
in an JZtxtcmd script. See Zmake.
The head of the zmake sub routine (example):
## ##The generate-script for a cc-target. ## arg cfgCheckDeps the path to the checkDependency-Config-file. Relativ to srcDir. ## arg srcDir the directory where checkDeps should be operate. ## arg objDir The directory where objects should be found. There "deps.txt" the dependency file is stored. ## sub cc(Obj target, String compilerOptions, String cfgCheckDeps = "make/cfgCheckDeps.cfg" , String srcDir, String objDir, String toolDir = "") { ....
In this example there is a String variable as argument objDir
which contains the absolute path to the object directory. A variable srcDir
is the path to the source directory, because the currdir
of the script may be another one. The argument cfgCheckDeps
is presetted with a default value for this example because the translator is part of a source pool with common settings.
Instantiation:
Obj checkDeps = new org.vishia.checkDeps_C.CheckDependencyFile(console, 1); checkDeps.setDirObj(<:><&objDir>/*.obj<.>); checkDeps.readCfgData(cfgCheckDeps, File: &srcDir); checkDeps.readDependencies(<:><&objDir>/deps.txt<.>); <+out><:n>checkDeps_C: <&objDir>/deps.txt read successfully<&newline><.+n>
The instance is created and referenced with the Obj checkDeps
as a local variable of the JZtxtcmd sub routine. Then some parameter are set, see the operation description in srcJava_Zbnf/org/vishia/checkDeps_C/CheckDependencyFile.
The file which contains currently dependencies deps.txt
is located in the object directory. If objects are existent, the file may be usefull to prevent unnecessary compilation.
If the object directory is clean, the deps.txt
may not existing too. Then no dependencies are known on start.
Check of any file:
for(input:inputs) { ..... ##The checkDeps algorithm itself may be unnecessary for compilation for compilation of all files. ##but it creates the obj directory tree which is necessary for compilation. ##The checkDeps checks whether the file is changed, delete the obj file on changed file. Obj infoDeps = checkDeps.processSrcfile(File: &input.file(), input.localfile()); <+out><&infoDeps><.+n> ##show state, info and file name on console.
The routine CheckDependencyFile.processSrcfile(...) checks the given source file with all depending files and deletes the existing obj file if the file should be compiled.
Conditional translation:
..... String cclabel = jzcmd.nextNr(); ##build a current number for labels. <+> REM call the compiler only if the object file is not found. if exist <&objDirW>\<&input.localname()>.obj goto :ok<&cclabel> echo compile <&input.localfile()> <&toolDir>cl.exe <&compilerOptions> <&_includePath> <&outOptions> <&input.absfileW()> >><&objDirW>\_cc_error.txt echo off if errorlevel 1 goto :error :ok<&cclabel> <.+> ..... }
The JZtxtcmd zmake subroutine generates a MS-Windows-batch file for this example. The advantages are:
The batchfile can be used to force compilation independent on the JZtxtcmd Zmake.
To immediately invoke the compiler in the JZcmdScript it needs an extra process for any source file.
The batchfile contains the checking of existing object file.
Write back dependencies and close:
##write back the checked dependencies: checkDeps.writeDependencies(); checkDeps.close();
The file given on CheckDependencyFile.readDependencies(sFilePath) is written newly - or firstly if it has not exist before.
Hint: The file contains some designations if some files are newly, see 9 Format of the dependency file. If you invoke the dependency algorithm a second time, there are not newly-designations because the sources are not changed in comparison to the run before. Then you keep a compareable file (text comparison) with the currently dependency situation in respect to an older dependency situation. You can see what has changed.
Topic:.CheckDeps_C.checkContent.
Last changed: 2012-01
It is the second approach of the CheckDeps_C tool. Some tools generate secondary source files though it is unnecessary. There content is not changed really, only some information written in comments for C-compilation are changed: Time stamp of generation, revision numbers, the person which is logged in in the computer etc. If all that files will be compilated it needs a lot of time.
The CheckDeps_C tool can work with mirrored sources. If the time stamp of a source is changed, it compares line per line with the mirror-source file. If only comment parts are changed, the associated object file is not deleted and the mirror-source is not renewed. A maker can work with the mirror source. Then it does not found a newly source and does not compile.
Topic:.CheckDeps_C.sourcepool.
Last changed: 2012-01
If the files are compiled with a make file which is generated from any tool, the source files are known in the makefile but the effort to control the CheckDeps_C to check one file after another is to high. Instead one or more directories which contains the source files are parametrized. The srcJava_Zbnf/org/vishia/checkDeps_C/CheckDeps with possible start from command line checks all that source files.
Topic:.CheckDeps_C..
Last changed: 2012-01
System header file (stdio.h
etc) are not checked because it should be assumed that they are unchanged. On the other hand the system headers may be more
complexely especially with conditional compilations (#if defined(...)
) as the users file. Therefore it may be an effort to check them.
The control file set with srcJava_Zbnf/org/vishia/checkDeps_C/CheckDependencyFile#readCfgData(java.lang.String) or the argument -cfg:file.cfg
from srcJava_Zbnf/org/vishia/checkDeps_C/CheckDeps#main(java.lang.String[]) has the following syntax, example:
$SBOX_DIR=./. -s=$(SBOX_DIR):source -s=$(SBOX_DIR):sourceSpecials/os_Windows_Msc6 -i=$(SBOX_DIR):include -i=$(SBOX_DIR):include/OSAL -i=$(SBOX_DIR):includeSpecials/os_Windows_Msc6 -y=D:/Progs/MSC6/act/Microsoft Visual Studio/VC98/Include
which is more formalistic:
{$envVar=value
}
{-s=
[$(envVar):
]sourcepath
}
{-i=
[$(envVar):
]includepath
}
{ -y=systemincludepath
}
A local variable can be defined and used in the shown kind.
Files are searched in alldirectories designated with the -s=path
. That is only by CheckDeps-start per command line.
Include files are searched by name in all pathes designated with -i=path
or -y=path
.
Files in the -y=path
is accepted but not tested. They are the system includes.
Topic:.CheckDeps_C.ifdef.
Last changed: 2017-08
If a user file contains
#ifdef DEFINE #include <something.h>
it is not regarded as a special case. All found #include
-statements are regarded as dependency.
Topic:.CheckDeps_C.format.
Last changed: 2012-01
The dependency file should not only used for internal storage of the depedency situation. It should be evaluated from the programmers too. Often some unfortunate includes forces unnecarry dependencies and lengthens the make times:
Project specific definitions may be assembled in one headerfile. It may be correct. This file may be included by many files, all of them depends of this.
Such a project file should be stable. Changes are done only if substantially project specifics are changed.
If this project file includes any special file, which may define a const value, and this file is changed frequently because other things than the constant value, it is a unfortunately dependency.
The dependency file should help to investigate whether a source file have to be compiled though the programmer is aware of no guilt. The programmer can detect which included file is to blame to force the compilation.
The dependency file may contain some designations if some files are detect as changed in an dependency run, see $chapter. If you invoke the dependency check a second time, there are not newly-designations because the sources are not changed yet. Then you keep a compareable file (text comparison) with the currently dependency situation in respect to an older dependency situation. You can see what has changed.
The next step may be: carefully change the include situation and the assignment of parts of sources to the header files. That is an important and difficult chapter of programming. If larger software projects are created with the same source pool, it is worthwile to improve that things.
The dependency file shows the following information:
#Special designation characters for change situation in the 2. column: # ^ Changed timestamp, but no content change outside comments in comparison with the mirror file. # & Recompile the file and all using files because an included file is changed. # $ Recompile like &, this file has a changed timestamp, but no content change outside comments too. # ! This file is changed, force recompile of all including files. #Include designation character in the 3. column: # - Direct included. # + Indirect included in another included file. # * This file includes the named file directly. It depends on it. # % This file includes the named file indirectly. It depends on it. File: 2012-12-25 16:16:46; 1356448606000; D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_Exception.h .includes: !- D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_MemC.h - D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_String.h + D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/OSAL/os_types_def_common.h + D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/includeSpecials/os_Windows_Msc6/os_types_def.h .is included in: * D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_ThreadContext.h * D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_Exception.c * D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_ExceptionPrintStacktrace.c * D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_MemC.c * D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_formatter.c % D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Jc/ObjectJc.h % D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Jc/ReflectionJc.h % D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_threadContext.c % D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/OSAL/Reflection_OSAL.c File: 2011-03-06 23:20:34; 1299450034000; D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/source/Fwc/fw_Exception.c .includes: &- D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_Exception.h - D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_SimpleC.h &- D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_ThreadContext.h - D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/OSAL/os_error.h !+ D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_MemC.h + D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/Fwc/fw_String.h + D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/include/OSAL/os_types_def_common.h + D:/vishia/Java2C/sf/Java2C/CRuntimeJavalike/includeSpecials/os_Windows_Msc6/os_types_def.h .is included in:
It is a part of the file. In this example the headerfile f_MemC.h
is changed. On any file it is listed which files includes this file and from which files this file is included.
To detect changed fiels search the character !
in the whole text. It shows the changed files. All depending files are found with them.
Any file can be searched in this text dependency file. Hint: to search a file use the absolute path like it is written here.
Use ; D:/path/to/file.c
with the colon, then you find the head line of the file, not an include line.