---
url: /api/scripts/builtin-modules/path.md
---
# path

The path operation module implements cross-platform path operations, which is a custom module of xmake.

For file I/O operations, see the [io module](/api/scripts/builtin-modules/io). For file and directory management, see the [os module](/api/scripts/builtin-modules/os).

## path.new

* Create a new path instance

#### Function Prototype

::: tip API

```lua
path.new(p: <string>, transform?: <function>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| p | Required. Path string |
| transform | Optional. Path transformation function |

#### Return Value

| Type | Description |
|------|-------------|
| path | Returns a path instance |

#### Usage

Create a path instance:

```lua
local p = path.new("/tmp/file.txt")
print(p:filename())  -- Output: file.txt
```

Using a transformation function:

```lua
local p = path.new("/tmp/a", function (raw_path)
    return "--key=" .. raw_path
end)
print(p:str())      -- Output: --key=/tmp/a
print(p:rawstr())   -- Output: /tmp/a
```

Or call the constructor directly:

```lua
local p = path("/tmp/file.txt")  -- Automatically creates an instance
print(p:filename())
```

Use [path.instance\_of](#path-instance_of) to check if a value is a path instance.

## path.normalize

* Normalize the path

#### Function Prototype

::: tip API

```lua
path.normalize(p: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| p | Required. Path string |

#### Return Value

| Type | Description |
|------|-------------|
| string | Returns the normalized path string |

#### Usage

Normalize the path (simplify `.` and `..`):

```lua
print(path.normalize("/tmp/./../file.txt"))  -- Output: /file.txt
print(path.normalize("c:\\tmp\\..\\.."))     -- On Windows: c:\\..
```

If you only need to convert path separators without simplifying `.` and `..`, use [path.translate](#path-translate).

## path.join

* Stitching path

#### Function Prototype

::: tip API

```lua
path.join(paths: <string|array>, ...)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| paths | Path string or array |
| ... | Variable arguments, can pass multiple path strings |

#### Usage

Adding multiple path items by splicing. Due to the path difference of `windows/unix` style, using api to append paths is more cross-platform, for example:

```lua
print(path.join("$(tmpdir)", "dir1", "dir2", "file.txt"))
```

The above splicing on Unix is equivalent to: `$(tmpdir)/dir1/dir2/file.txt`, and on Windows is equivalent to: `$(tmpdir)\\dir1\\dir2\\file.txt`

If you find this cumbersome and not clear enough, you can use: [path.translate](#path-translate) to format the conversion path string to the format supported by the current platform.

## path.translate

* Convert path to the path style of the current platform

#### Function Prototype

::: tip API

```lua
path.translate(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to convert |

#### Usage

Formatting converts the specified path string to the path style supported by the current platform, and supports the path string parameter of the `windows/unix` format to be passed in, even mixed, such as:

```lua
print(path.translate("$(tmpdir)/dir/file.txt"))
print(path.translate("$(tmpdir)\\dir\\file.txt"))
print(path.translate("$(tmpdir)\\dir/dir2//file.txt"))
```

The path strings of the above three different formats, after being standardized by `translate`, will become the format supported by the current platform, and the redundant path separator will be removed.

If you also need to simplify `.` and `..`, use [path.normalize](#path-normalize).

## path.basename

* Get the file name with no suffix at the end of the path

#### Function Prototype

::: tip API

```lua
path.basename(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |

#### Usage

```lua
print(path.basename("$(tmpdir)/dir/file.txt"))
```

The result is: `file`

To get the filename with extension, use [path.filename](#path-filename); for the extension, use [path.extension](#path-extension); for the directory part, use [path.directory](#path-directory).

## path.filename

* Get the file name with the last suffix of the path

#### Function Prototype

::: tip API

```lua
path.filename(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |

#### Usage

```lua
print(path.filename("$(tmpdir)/dir/file.txt"))
```

The result is: `file.txt`

## path.extension

* Get the suffix of the path

#### Function Prototype

::: tip API

```lua
path.extension(path: <string>, level?: <number>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |
| level | Optional. Extension level, default is 1 |

#### Usage

```lua
print(path.extension("$(tmpdir)/dir/file.txt"))
```

The result is: `.txt`

You can specify the `level` parameter to get multi-level extensions, for example:

```lua
print(path.extension("/tmp/file.tar.gz", 2))
```

The result is: `.tar.gz`

## path.directory

* Get the directory name of the path

#### Function Prototype

::: tip API

```lua
path.directory(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |

#### Usage

```lua
print(path.directory("$(tmpdir)/dir/file.txt"))
```

The result is: `$(tmpdir)/dir`

## path.relative

* Convert to relative path

#### Function Prototype

::: tip API

```lua
path.relative(path: <string>, rootdir: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to convert |
| rootdir | Root directory for relative conversion |

#### Usage

```lua
print(path.relative("$(tmpdir)/dir/file.txt", "$(tmpdir)"))
```

The result is: `dir/file.txt`

The second parameter is to specify the relative root directory. If not specified, the default is relative to the current directory:

```lua
os.cd("$(tmpdir)")
print(path.relative("$(tmpdir)/dir/file.txt"))
```

The result is the same.

The reverse operation is [path.absolute](#path-absolute), which converts relative paths to absolute paths. Use [path.is\_absolute](#path-is_absolute) to check if a path is absolute.

## path.absolute

* Convert to absolute path

#### Function Prototype

::: tip API

```lua
path.absolute(path: <string>, rootdir: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to convert |
| rootdir | Root directory for absolute conversion |

#### Usage

```lua
print(path.absolute("dir/file.txt", "$(tmpdir)"))
```

The result is: `$(tmpdir)/dir/file.txt`

The second parameter is to specify the relative root directory. If not specified, the default is relative to the current directory:

```lua
os.cd("$(tmpdir)")
print(path.absolute("dir/file.txt"))
```

The result is the same.

The reverse operation is [path.relative](#path-relative), which converts absolute paths to relative paths.

## path.is\_absolute

* Determine if it is an absolute path

#### Function Prototype

::: tip API

```lua
path.is_absolute(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to check |

#### Usage

```lua
if path.is_absolute("/tmp/file.txt") then
    -- if it is an absolute path
end
```

## path.split

* Split the path by the separator

#### Function Prototype

::: tip API

```lua
path.split(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to split |

#### Usage

```lua
print(path.split("/tmp/file.txt"))
```

The result is: `{ "tmp", "file.txt" }`

The reverse operation is [path.join](#path-join), which joins multiple paths into one.

## path.sep

* Get the path separator of the current platform

#### Function Prototype

::: tip API

```lua
path.sep()
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| None | No parameters |

#### Usage

```lua
print(path.sep())
```

The result is: `/` on Unix, `\` on Windows.

## path.islastsep

* Get if the last character is a separator

#### Function Prototype

::: tip API

```lua
path.islastsep(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to check |

#### Usage

```lua
if (path.islastsep("/tmp/dir/")) then
    -- if the last character is a separator
end
```

## path.splitenv

* Split an environment variable value into an array of paths

#### Function Prototype

::: tip API

```lua
path.splitenv(envpath: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| envpath | Environment variable path string |

#### Usage

```lua
local paths = path.splitenv(vformat("$(env PATH)"))

-- for windows
local paths = path.splitenv("C:\\Windows;C:\\Windows\\System32")
-- got { "C:\\Windows", "C:\\Windows\\System32" }

-- for *nix
local paths = path.splitenv("/usr/bin:/usr/local/bin")
-- got { "/usr/bin", "/usr/local/bin" }
```

The result is an array of strings, each item is a path in the input string.

The reverse operation is [path.joinenv](#path-joinenv), which joins a path array into an environment variable string. Use [os.getenv](/api/scripts/builtin-modules/os#os-getenv) to get environment variable values.

## path.joinenv

* Join path array into an environment variable string

#### Function Prototype

::: tip API

```lua
path.joinenv(paths: <array>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| paths | Array of path strings |

#### Usage

```lua
-- on Unix
print(path.joinenv({"/usr/bin", "/usr/local/bin"}))
-- Output: /usr/bin:/usr/local/bin

-- on Windows
print(path.joinenv({"C:\\Windows", "C:\\Windows\\System32"}))
-- Output: C:\Windows;C:\Windows\System32
```

The reverse operation is [path.splitenv](#path-splitenv), which splits an environment variable string into a path array. The environment variable separator for the current platform can be obtained via [path.envsep](#path-envsep).

## path.envsep

* Get the environment variable path separator of the current platform

#### Function Prototype

::: tip API

```lua
path.envsep()
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| None | No parameters |

#### Usage

```lua
print(path.envsep())
```

The result is: `:` on Unix, `;` on Windows.

## path.pattern

* Convert path pattern to lua pattern

#### Function Prototype

::: tip API

```lua
path.pattern(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string to convert |

#### Usage

```lua
print(path.pattern("/tmp/file.txt"))
```

The result is: `/[tT][mM][pP]/[fF][iI][lL][eE]%.[tT][xX][tT]`

## path.unix

* Convert path to Unix style

#### Function Prototype

::: tip API

```lua
path.unix(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |

#### Usage

Replace all path separators with `/`, typically used on Windows when Unix-style paths are needed:

```lua
print(path.unix("C:\\Windows\\System32"))
-- Output: C:/Windows/System32
```

If you need Cygwin-style conversion (with drive letter transformation), use [path.cygwin](#path-cygwin). To convert to the native style of the current platform, use [path.translate](#path-translate).

## path.cygwin

* Convert path to Cygwin style

#### Function Prototype

::: tip API

```lua
path.cygwin(path: <string>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| path | Path string |

#### Usage

Convert a Windows path to Cygwin style, transforming the drive letter `C:\` to `/c/` and replacing `\` with `/`:

```lua
print(path.cygwin("C:\\Windows\\System32"))
-- Output: /c/Windows/System32
```

## path.instance\_of

* Check if a value is a path instance

#### Function Prototype

::: tip API

```lua
path.instance_of(p: <any>)
```

:::

#### Parameter Description

| Parameter | Description |
|-----------|-------------|
| p | The value to check |

#### Return Value

| Type | Description |
|------|-------------|
| boolean | Returns true if it is a path instance, false otherwise |

#### Usage

```lua
local p = path.new("/tmp/file.txt")
print(path.instance_of(p))      -- Output: true
print(path.instance_of("/tmp")) -- Output: false
```

Path instances are created with [path.new](#path-new).
