Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for [vcpkg].overlay-triplets #160

Merged
merged 3 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 43 additions & 13 deletions docs/cmake-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,18 @@ Variables emit a [`set`](https://cmake.org/cmake/help/latest/command/set.html) a

```toml
[vcpkg]
version = "2024.03.25"
url = "https://github.com/microsoft/vcpkg/archive/refs/tags/2024.03.25.tar.gz"
version = "2024.11.16"
url = "https://github.com/microsoft/vcpkg/archive/refs/tags/2024.11.16.tar.gz"
packages = ["fmt", "zlib"]
overlay-ports = ["my-ports"]
overlay-triplets = ["my-triplets"]
```

The vcpkg `version` will automatically generate the `url` from the [official repository](https://github.com/microsoft/vcpkg/releases). For a custom registry you can specify your own `url` (and omit the `version`). You can browse available packages on [vcpkg.io](https://vcpkg.io/en/packages.html).
The vcpkg `version` will automatically generate the `url` from the [official repository](https://github.com/microsoft/vcpkg/releases). For a custom registry you can specify your own `url` (and omit the `version`). You can browse available packages on [vcpkg.io](https://vcpkg.io/en/packages.html) or [vcpkg.link](https://vcpkg.link).

To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`. To disable the [default features](https://learn.microsoft.com/en-us/vcpkg/concepts/default-features) you can do: `cpp-httplib[core,openssl]`

The `overlay-ports` feature allows you to embed vcpkg ports inside your project, without having to fork the main vcpkg registry or creating a custom registry. You can find more information in the relevant [documentation](https://learn.microsoft.com/en-us/vcpkg/concepts/overlay-ports).
The `overlay-ports` feature allows you to embed vcpkg ports inside your project, without having to fork the main vcpkg registry or creating a custom registry. You can find more information in the relevant [documentation](https://learn.microsoft.com/en-us/vcpkg/concepts/overlay-ports). The `overlay-triplets` feature allows you to customize triplets and change the default behavior (for example always preferring static libraries on Windows). To specify both in one go you can do `[vcpkg].overlay = "my-overlay"`.

## Packages

Expand Down Expand Up @@ -218,28 +219,28 @@ Table keys that match CMake variable names (`[A-Z_]+`) will be passed to the [`F
[target.mytarget]
condition = "mycondition"
alias = "mytarget::mytarget"
type = "static" # executable, shared (DLL), static, interface, object, library, custom
type = "static" # executable, library, shared (DLL), static, interface, object, custom
headers = ["src/mytarget.h"]
sources = ["src/mytarget.cpp"]
msvc-runtime = "" # dynamic (implicit default), static

# The keys below match the target_xxx CMake commands
# Keys prefixed with private- will get PRIVATE visibility
compile-definitions = [""]
compile-definitions = [""] # preprocessor define (-DFOO)
private-compile-definitions = [""]
compile-features = [""]
compile-features = [""] # C++ standard version (cxx_std_20)
private-compile-features = [""]
compile-options = [""]
compile-options = [""] # compiler flags
private-compile-options = [""]
include-directories = [""]
include-directories = [""] # include paths/directories
private-include-directories = [""]
link-directories = [""]
link-directories = [""] # library directories
private-link-directories = [""]
link-libraries = [""]
link-libraries = [""] # dependencies
private-link-libraries = [""]
link-options = [""]
link-options = [""] # linker flags
private-link-options = [""]
precompile-headers = [""]
precompile-headers = [""] # precompiled headers
private-precompile-headers = [""]

cmake-before = """
Expand All @@ -258,6 +259,35 @@ CXX_STANDARD_REQUIRED = true
FOLDER = "MyFolder"
```

A table mapping the cmkr features to the relevant CMake construct and the relevant documentation pages:

| cmkr | CMake construct | Description |
| ---- | ----- | ----------- |
| `alias` | [Alias Libraries](https://cmake.org/cmake/help/latest/command/add_library.html#alias-libraries) | Create an [alias target](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#alias-targets), used for namespacing or clarity. |
| `sources` | [`target_sources`](https://cmake.org/cmake/help/latest/command/target_sources.html) | Source files (`PRIVATE` except `interface` targets). |
| `headers` | [`target_sources`](https://cmake.org/cmake/help/latest/command/target_sources.html) | For readability (and future packaging). |
| `msvc-runtime` | [`MSVC_RUNTIME_LIBRARY`](https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html) | The [CMP0091](https://cmake.org/cmake/help/latest/policy/CMP0091.html) policy is set automatically. |
| `compile-definitions` | [`target_compile_definitions`](https://cmake.org/cmake/help/latest/command/target_compile_definitions.html) | Adds a macro definition (define, `-DMYMACRO=XXX`). |
| `compile-features` | [`target_compile_features`](https://cmake.org/cmake/help/latest/command/target_compile_features.html) | Specifies the C++ standard version (`cxx_std_20`). |
| `compile-options` | [`target_compile_options`](https://cmake.org/cmake/help/latest/command/target_compile_options.html) | Adds compiler flags. |
| `include-directories` | [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) | Adds include directories. |
| `link-directories` | [`target_link_directories`](https://cmake.org/cmake/help/latest/command/target_link_directories.html) | Adds library directories. |
| `link-libraries` | [`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) | Adds library dependencies. |
| `link-options` | [`target_link_options`](https://cmake.org/cmake/help/latest/command/target_link_options.html) | Adds linker flags. |
| `precompile-headers` | [`target_precompile_headers`](https://cmake.org/cmake/help/latest/command/target_precompile_headers.html) | Specifies precompiled headers. |
| `properties` | [`set_target_properties`](https://cmake.org/cmake/help/latest/command/set_target_properties.html) | See [properties on targets](https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets) for more information. |

The default [visibility](/basics) is as follows:

| Type | Visibility |
| ------------ | ----------- |
| `executable` | `PRIVATE` |
| `library` | `PUBLIC` |
| `shared` | `PUBLIC` |
| `static` | `PUBLIC` |
| `object` | `PUBLIC` |
| `interface` | `INTERFACE` |

## Templates

To avoid repeating yourself you can create your own target type and use it in your targets:
Expand Down
7 changes: 5 additions & 2 deletions docs/examples/compile-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ nav_order: 9

# Compiler flags

Example project that sets compiler/linker flags for various platforms.
Example project that sets compiler flags and preprocessor defines for various platforms.

```toml
[project]
Expand All @@ -20,11 +20,14 @@ description = "Compiler flags"
type = "executable"
sources = ["src/main.cpp"]
msvc.compile-options = ["/W2"]
msvc.compile-definitions = ["PLATFORM=\"msvc\""]
gcc.compile-options = ["-Wall"]
gcc.compile-definitions = ["PLATFORM=\"gcc\""]
clang.compile-options = ["-Wall"]
clang.compile-definitions = ["PLATFORM=\"clang\""]
```

The `hello` target uses [conditions](/cmake-toml#conditions) to set different compiler flags depending on the platform. See the [targets](/cmake-toml/#targets) documentation for other things you can set.
The `hello` target uses [conditions](/cmake-toml#conditions) to set different compiler flags and definitions depending on the platform. See the [targets](/cmake-toml/#targets) documentation for other things you can set.

_Note_: In general you only want to specify flags _required_ to compile your code without errors.

Expand Down
9 changes: 4 additions & 5 deletions docs/examples/vcpkg.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@ nav_order: 4

# Dependencies from vcpkg

Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://vcpkg.io/) and links an `example` target to it:
Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://github.com/microsoft/vcpkg) and links an `example` target to it:

```toml
[project]
name = "vcpkg"
description = "Dependencies from vcpkg"

# See https://github.com/microsoft/vcpkg/releases for vcpkg versions
# See https://vcpkg.io/en/packages.html for available packages
# See https://vcpkg.io/en/packages or https://vcpkg.link for available packages
[vcpkg]
version = "2024.03.25"
version = "2024.11.16"
packages = ["fmt"]

[find-package]
fmt = {}
[find-package.fmt]

[target.example]
type = "executable"
Expand Down
3 changes: 3 additions & 0 deletions include/project_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ struct Vcpkg {
};

std::vector<Package> packages;

// https://github.com/Microsoft/vcpkg-docs/blob/main/vcpkg/users/buildsystems/cmake-integration.md
std::vector<std::string> overlay_ports;
std::vector<std::string> overlay_triplets;

bool enabled() const {
return !packages.empty();
Expand Down
40 changes: 17 additions & 23 deletions src/cmake_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,22 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
endl();
}

if (project.vcpkg.enabled()) {
comment("vcpkg settings");
auto emit_overlay = [&cmd](const std::string &name, const std::vector<std::string> &overlay) {
if (!overlay.empty()) {
for (const auto &directory : overlay) {
if (!fs::is_directory(directory)) {
throw std::runtime_error("[vcpkg] overlay is not a directory: " + directory);
}
}
cmd("set")(name, overlay);
}
};
emit_overlay("VCPKG_OVERLAY_PORTS", project.vcpkg.overlay_ports);
emit_overlay("VCPKG_OVERLAY_TRIPLETS", project.vcpkg.overlay_triplets);
}

gen.conditional_includes(project.include_before);
gen.conditional_cmake(project.cmake_before);

Expand Down Expand Up @@ -996,29 +1012,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
ofs << " ],\n";
ofs << " \"description\": \"" << escape(project.project_description) << "\",\n";
ofs << " \"name\": \"" << escape(vcpkg_escape_identifier(project.project_name)) << "\",\n";
ofs << " \"version-string\": \"none\"";
const auto &overlay_ports = project.vcpkg.overlay_ports;
if (!overlay_ports.empty()) {
ofs << ",\n";
// Reference: https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json#vcpkg-configuration
ofs << " \"vcpkg-configuration\": {\n";
ofs << " \"overlay-ports\": [\n";
for (size_t i = 0; i < overlay_ports.size(); i++) {
const auto &directory = overlay_ports[i];
if (!fs::is_directory(directory)) {
throw std::runtime_error("[vcpkg].overlay-ports is not a directory: " + directory);
}
ofs << " \"" << escape(directory) << "\"";
if (i > 0) {
ofs << ",";
}
ofs << "\n";
}
ofs << " ]\n";
ofs << " }\n";
} else {
ofs << "\n";
}
ofs << " \"version-string\": \"none\"\n";
ofs << "}\n";
}

Expand Down
15 changes: 14 additions & 1 deletion src/project_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,20 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p
vcpkg.packages.emplace_back(std::move(package));
}

v.optional("overlay-ports", vcpkg.overlay_ports);
if (v.contains("overlay")) {
std::string overlay;
v.optional("overlay", overlay);
vcpkg.overlay_triplets = vcpkg.overlay_ports = {overlay};
if (v.contains("overlay-ports")) {
throw_key_error("[vcpkg].overlay was already specified", "overlay-ports", v.find("overlay-ports"));
}
if (v.contains("overlay-triplets")) {
throw_key_error("[vcpkg].overlay was already specified", "overlay-triplets", v.find("overlay-triplets"));
}
} else {
v.optional("overlay-ports", vcpkg.overlay_ports);
v.optional("overlay-triplets", vcpkg.overlay_triplets);
}
}

checker.check(conditions, true);
Expand Down
3 changes: 2 additions & 1 deletion tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# These will be generated by cmkr, so no point in tracking them
**/CMakeLists.txt
**/cmkr.cmake
**/cmkr.cmake
**/vcpkg.json
7 changes: 5 additions & 2 deletions tests/compile-options/cmake.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Example project that sets compiler/linker flags for various platforms.
# Example project that sets compiler flags and preprocessor defines for various platforms.

[project]
name = "compile-options"
Expand All @@ -8,8 +8,11 @@ description = "Compiler flags"
type = "executable"
sources = ["src/main.cpp"]
msvc.compile-options = ["/W2"]
msvc.compile-definitions = ["PLATFORM=\"msvc\""]
gcc.compile-options = ["-Wall"]
gcc.compile-definitions = ["PLATFORM=\"gcc\""]
clang.compile-options = ["-Wall"]
clang.compile-definitions = ["PLATFORM=\"clang\""]

# The `hello` target uses [conditions](/cmake-toml#conditions) to set different compiler flags depending on the platform. See the [targets](/cmake-toml/#targets) documentation for other things you can set.
# The `hello` target uses [conditions](/cmake-toml#conditions) to set different compiler flags and definitions depending on the platform. See the [targets](/cmake-toml/#targets) documentation for other things you can set.
# _Note_: In general you only want to specify flags _required_ to compile your code without errors.
9 changes: 4 additions & 5 deletions tests/vcpkg/cmake.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://vcpkg.io/) and links an `example` target to it:
# Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://github.com/microsoft/vcpkg) and links an `example` target to it:

[project]
name = "vcpkg"
description = "Dependencies from vcpkg"

# See https://github.com/microsoft/vcpkg/releases for vcpkg versions
# See https://vcpkg.io/en/packages.html for available packages
# See https://vcpkg.io/en/packages or https://vcpkg.link for available packages
[vcpkg]
version = "2024.03.25"
version = "2024.11.16"
packages = ["fmt"]

[find-package]
fmt = {}
[find-package.fmt]

[target.example]
type = "executable"
Expand Down
11 changes: 0 additions & 11 deletions tests/vcpkg/vcpkg.json

This file was deleted.