A tree structure specifies all the source files in the project. File and directory names must be enclosed in double quotes. A string represents a directory name if and only if it is followed by a left brace.
It is conventional (but not required) to list directories before files.
{
"dir1"
{
"dir2"
{
"file1.cpp"
"file1.h"
"file2.cpp"
"file2.h"
}
"dir3"
{
"dir4"
{
"file4.cpp"
"file4.h"
}
"file3.cpp"
"file3.h"
}
}
"file5.cpp"
"file5.h"
}
In this case the directory structure on disk is reflected in the folder structure presented in MSVC, using folder icons for directories dir1, dir2, dir3 and dir4. We will see below that it is possible to break this direct correspondence, if it’s appropriate. The outermost curly braces is always assumed to enclose the content of the project directory (see section 3.2).
The Xcpp build system supports wild cards when specifying files/directories to add to a project. Consider the following specification of the files in a project:
{
"src"
{
"ArchiveTests.cpp"
"CacheMapTests.cpp"
"CRCTests.cpp"
"FileTests.cpp"
"GuidTests.cpp"
"HeapAllocTests.cpp"
"HexTests.cpp"
"IndentingStringStreamTests.cpp"
"Lessons.cpp"
"MD5Tests.cpp"
"MultiSubStringTests.cpp"
"PagedBufferTests.cpp"
"ParserDemo.cpp"
"PseudoRandomTests.cpp"
"SessionValueCacheTests.cpp"
"ThreadTests.cpp"
"RefCounter.cpp"
"VariableLengthSerialiseTests.cpp"
"VectorTests.cpp"
"VectorTests.h"
"xstringTests.cpp"
"xostreamTests.cpp"
"txUtils.cpp"
"StdAfx.cpp" : +cpp { /Yc"StdAfx.h" }
"StdAfx.h"
}
}
An alternative is for the files in the project to be determined automatically from the file system:
{
"src"
{
"StdAfx.cpp" : +cpp { /Yc"StdAfx.h" }
"*.cpp"
"*.h"
}
}
Wild card searching is performed against the virtual tree, and therefore may involve searching through multiple physical trees on a development machine.
Note that StdAfx.cpp isn’t added twice. In general, wild card searches never add a folder or file with the same logical path more than once.
We refer to a string such as "*.cpp" as a name pattern. A name pattern cannot contain any slash characters. Most generally name patterns can be used to filter either file names or directory names. For the file named "foo.bar", the following name patterns all successfully match the file name:
*
f*
*.*
*.b*
foo.bar*
f*.bar
f*.*r
f??.bar
???.???
f*.b?r
*?oo.bar
whereas the following name patterns fail:
*?foo.bar
f?.bar
g*
*.exe
A name filter is either a prescriptive or proscriptive set of name patterns,
A name pattern is represented using a double quoted string. A name filter consists optionally of a ’+’ or ’-’, then either a single pattern or else a list of zero or more white space delimited patterns in square brackets. An initial ’-’ means the specification is proscriptive (rather than prescriptive, which is the default). With the ’-’ a name is rejected if it matches any of the patterns, whereas with ’+’ a name is accepted if it matches any of the patterns. The name filter -[] means reject nothing, or in other words accept anything, and is equivalent to "*".
Note that the following four lines are all equivalent name filters:
"*.cpp"
["*.cpp"]
+"*.cpp"
+["*.cpp"]
There is support for recursion through directories by appending an asterisk after the file name filter. E.g.
{
"dir1"
{
"dir2"
{
["*.cpp" "*.h"] *
}
}
}
In this case all .cpp and .h files under dir2 or any of its subdirectories recursively are added to the project. This could cause many folders to be shown under dir2 in MSVC. Note that only non-empty directories are added to the .vcproj file and therefore appear in MSVC.
Recursion through directories can have the structure flattened as it appears in MSVC. This is easily achieved by prefixing the asterisk with the keyword flat as follows:
{
"dir1"
{
"dir2"
{
["*.cpp" "*.h"] flat *
}
}
}
Now all the .cpp and .h files are displayed in MSVC in a single flat list under dir2.
It is possible to rename a folder as it appears in MSVC. For example:
{
"dir1"
{
"dir2" as "x"
{
["*.cpp" "*.h"] flat *
}
}
}
Now directory dir2 will appear as a folder named x in MSVC.
'as' doesn’t just allow for renaming. It can also allow a folder to be added to MSVC where there is no corresponding directory in the virtual tree, and vice versa. This is achieved by using empty strings on either side of as. E.g.
{
"" as "Header"
{
"*.h" flat *
}
"" as "Source"
{
"*.cpp" flat *
}
}
In this case there are folders in MSVC named Header and Source but no corresponding directories in the virtual tree. Conversely, in the following example dir2 has been aliased to an empty string. A flattening affect is achieved, in that all the .h files appear directly under dir1 instead of dir2.
{
"dir1"
{
"dir2" as ""
{
"*.h"
}
}
}
Use the following mnemonic to help understand this: "virtual-tree-directory-name" as "MSVC-folder-name"
It is permissible for directory names to contain ’..’ in the manner illustrated below to step upwards out of the project directory.
For example:
$TARGET_TYPE = "Utility Project"
$ROOT_TO_PROJDIR = "x/y/z"
{
"../../.." {"*.xcws"*} // $
"../.." {} // x
".." {} // y
"" {} // z
}
"../../.." is a right inverse of $ROOT_TO_PROJDIR and therefore represents the root of the virtual tree. It is displayed as a folder named $ within MSVC. The pattern "*.xcws" is applied recursively to the virtual tree under $, so we end up with every Xcpp workspace file in the entire virtual tree.
Using "../.." denotes the directory named x, and would be displayed as a folder named x in MSVC.
There is a predefined variable named $PROJDIR_TO_ROOT which is calculated as a right inverse of $ROOT_TO_PROJDIR. Therefore another way to show all the workspaces in the virtual tree is:
$TARGET_TYPE = "Utility Project"
$ROOT_TO_PROJDIR = "x/y/z"
{
"$(PROJDIR_TO_ROOT)" as "Workspaces"
{
"*.xcws" flat *
}
}
In this case the folder appearing in MSVC has been renamed Workspaces, and the .xcws files in the folder are displayed in a flat list.