-
Notifications
You must be signed in to change notification settings - Fork 96
Q# External Dependencies (Libraries)
There are two ways to take a dependency on an external Q# project. The first is a local dependency, and the second is a GitHub dependency. The easiest way to add a dependency is to use the Add Q# project reference
command from the VS Code command palette with a qsharp.json
manifest file open. (It is also available as a right-click context menu on qsharp.json
files).
To add a dependency manually, add a "dependencies"
property to your qsharp.json
project manifest file. A local dependency looks like this:
{
"author": "your name here",
"license": "your chosen license here",
"dependencies": {
"SomeDependency": {
"path": "/path/to/other/project/on/disk"
}
}
}
And a GitHub dependency looks like this:
{
"author": "your name here",
"license": "your chosen license here",
"dependencies": {
"SomeDependency": {
"github": {
"owner": "GitHubUser",
"repo": "GitHubRepoName",
"ref": "CommitHash"
}
}
}
}
Note: for GitHub dependencies, the ref
property refers to a Github refspec, however we recommend always using a commit hash.
If the GitHub dependency is in a subdirectory of the repository, an optional "path"
property can be used to specify that subdirectory:
{
"author": "your name here",
"license": "your chosen license here",
"dependencies": {
"SomeDependency": {
"github": {
"owner": "GitHubUser",
"repo": "GitHubRepoName",
"ref": "CommitHash",
"path": "/path/to/dependency"
}
}
}
}
After following the steps in the above section, you'll be able to access items that have been exported from the external project. They'll be available in a namespace defined as the name given to the dependency in the qsharp.json
project manifest file. As an example, consider the following manifest file:
{
"author": "your name here",
"license": "your chosen license here",
"dependencies": {
"SomeDependency": {
"path": "/path/to/other/project/on/disk"
}
}
}
In this manifest file, we define an external dependency called "SomeDependency"
. This external project will therefore show up under the namespace SomeDependency
. To access an exported callable Bar()
from "SomeDependency"
, we can call it as such: SomeDependency.Bar();
. To import all items from an external project, we can use a glob import: import SomeDependency.*;
. This is analogous to the existing open
syntax: open SomeDependency;
.
Import statements allow for either importing individual items, or glob-importing entire namespaces into the current scope. Imports can also be used to alias items. Here are a few examples:
-
import Foo.Bar;
: imports a single item calledBar
from the namespaceFoo
. -
import Foo.Bar as Foobar;
: imports a single item calledBar
from the namespaceFoo
, but makes it accessible in the local scope asFoobar
. -
import Foo.*;
: import all items from the namespaceFoo
. -
import Foo as F;
import the namespaceFoo
asF
, items insideFoo
are now accessible viaF
. For example,Foo.Bar
is now accessible asF.Bar
. -
import Foo.Bar, Foo as F, Foo.Bar as Foobar;
: imports can be combined into one line.
Q# Projects are a great way to import external code. But what if you want to publish your project as a library, so others can import it? What if you want to become a Q# library author? A set of features has been added to enable you to define your project's exported API.
Any callable, type, or namespace can be exported for external usage. Consider the following Q# project structure:
.
├── qsharp.json
└── src/
└── MathStuff.qs
Any files included in the project must be listed in the qsharp.json
file under "files"
, so the above project's manifest file should look like this:
{
"author": "your name here",
"license": "your chosen license here",
"files": [ "src/MathStuff.qs" ]
}
In the QDK VS Code extension, a command exists to automatically populate "files"
. With the qsharp.json
manifest file open in the editor, access the VS Code command palette menu and run Q#: populate qsharp.json files list
. (You can also right click on a qsharp.json
file and the command is on the context menu).
Now, consider the contents of MathStuff.qs
:
function Add(a: Int, b: Int): Int {
return a + b;
}
To export Add
, we add an export statement:
function Add(a: Int, b: Int): Int {
return a + b;
}
export Add;
The callable Add
will show up in this project's API as MathStuff.Add()
, because export statements export items from the namespace they were exported from. That means that if you export Add()
from the namespace Foo.Bar
, it will show up to consumers of the project as Foo.Bar.Add()
.
In a similar manner to imports, exports can also be aliased:
function Add(a: Int, b: Int): Int {
return a + b;
}
export Add as MyAdd;
Export statements export items for external projects. All items are available to other namespaces within the same project by default, without any exporting needed.
In a project, if there's a namespace called Main
, it is treated as the root of the project. So, if you have the below structure:
src/
Foo.qs
Main.qs
Bar.qs
and a consumer of the project with the manifest:
{
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"MyLibrary": {
"path": "/path/to/other/project/on/disk"
}
}
}
Anything exported from Main.qs
, say a callable X
, will show up in the consumer of the project as MyLibrary.X()
. The behavior of items exported from Foo.qs
and Bar.qs
is unchanged; an item X
exported from these namespaces would show up as MyLibrary.Foo.X()
and MyLibrary.Bar.X()
.