JamPlus manual
|
The following are various methods to write a file within Jam.
Copy the following to a Jamfile.jam
file.
Note that $(1)
ends up being the filename file.txt
, so the echo
line will end up writing My custom file
to file.txt
.
If we run Jam at this point, file.txt
will not be written:
file.txt
is not in the dependency chain yet, so it won't be automatically build. It can be written by running jam with the target name:
Building with jam again does no additional work:
It would be nice if we could run jam without specifying the file.txt
target. We can throw it into the all
dependency chain to make this happen, since all
is the default target when jam is run without arguments.
Add a Depends call to Jamfile.jam
.
Jam informs us that the target count has gone up, but nothing builds. The file is already there on disk from the last time we ran jam.
There is a target called clean
that will remove anything it depends on from the disk. If file.txt
is added to the clean
target, then running jam clean
will remove file.txt
:
Change Jamfile.jam
to:
Then clean up the already existing file.txt
by running jam with the clean
target.
Run jam again without a target to cause file.txt
to be written to disk:
We need to write different text to the file in the WriteOneLineCustomFile
rule, so the WriteOneLineCustomFile
action is updated to this.
And then running Jam:
Nothing happened.
In Jam, changes to the script lines in actions are not factored into the build. Out of box, Jam performs build operations based on timestamps, but in this example, there are no timestamps to be considered. We have to tell Jam the action changed in another way.
The UseCommandLine rule can be used for this. UseCommandLine
adds user-defined data to the build calculations. If that user-defined data changes from one build to another, the target will be updated regardless of timestamps. Despite its name, UseCommandLine
does not change the command line of any tool used in the build; it only performs additional dependency calculations.
Run jam:
Good. file.txt
gets updated.
Any time a change is made to the text in WriteOneLineCustomFile
, we should also update the UseCommandLine
version to get it to build.
This feels, though, as if mistakes could be made frequently. We can build a better approach and make WriteOneLineCustomFile
more reusable in the process:
Within WriteOneLineCustomFile
, we are only writing a single line of content. Jam's list expansion features could be used to automatically expand the "echo" lines into as many as we provide, but it is ugly. A better way is to use the special expansion syntax for writing files. In Jambase.jam
, this syntax is hidden within rule WriteFile.
We can use this to write multiple lines to the file:
In fact, Jam provides WriteFileContents to make this as easy to use as possible:
In all cases, changing the content will result in Jam updating the generated target file.txt
.
Using file.txt
everywhere gets harder and harder to maintain.
Let's swap it out for a variable instead:
When the target needs to be written into another directory, Jam provides a couple different approaches to this.
The easiest is to use the MakeLocate rule to have Jam add a dependency on the directory the target is to be written into. Jam will check first whether the directory exists. If it doesn't, the directory will be created and then the target file can be written.
Make note that the target
is still file.txt
. The directory that file.txt
is to be put in, the/output/directory
, is assigned to file.txt
's LOCATE
setting. This keeps the target name clean and allows simple reassignment of the output directory via LOCATE
. See the documentation for LOCATE for more information.
target
can also be a full relative or absolute path. We just have to call MakeLocate
with the combine
option.