Skip to content

Commit efbfca2

Browse files
authored
Merge pull request #160 from build-cpp/vcpkg-triplets
Add support for `[vcpkg].overlay-triplets`
2 parents dea41d8 + 78bcf2a commit efbfca2

File tree

10 files changed

+97
-63
lines changed

10 files changed

+97
-63
lines changed

docs/cmake-toml.md

+43-13
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,18 @@ Variables emit a [`set`](https://cmake.org/cmake/help/latest/command/set.html) a
160160

161161
```toml
162162
[vcpkg]
163-
version = "2024.03.25"
164-
url = "https://github.com/microsoft/vcpkg/archive/refs/tags/2024.03.25.tar.gz"
163+
version = "2024.11.16"
164+
url = "https://github.com/microsoft/vcpkg/archive/refs/tags/2024.11.16.tar.gz"
165165
packages = ["fmt", "zlib"]
166166
overlay-ports = ["my-ports"]
167+
overlay-triplets = ["my-triplets"]
167168
```
168169

169-
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).
170+
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).
170171

171172
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]`
172173

173-
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).
174+
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"`.
174175

175176
## Packages
176177

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

226227
# The keys below match the target_xxx CMake commands
227228
# Keys prefixed with private- will get PRIVATE visibility
228-
compile-definitions = [""]
229+
compile-definitions = [""] # preprocessor define (-DFOO)
229230
private-compile-definitions = [""]
230-
compile-features = [""]
231+
compile-features = [""] # C++ standard version (cxx_std_20)
231232
private-compile-features = [""]
232-
compile-options = [""]
233+
compile-options = [""] # compiler flags
233234
private-compile-options = [""]
234-
include-directories = [""]
235+
include-directories = [""] # include paths/directories
235236
private-include-directories = [""]
236-
link-directories = [""]
237+
link-directories = [""] # library directories
237238
private-link-directories = [""]
238-
link-libraries = [""]
239+
link-libraries = [""] # dependencies
239240
private-link-libraries = [""]
240-
link-options = [""]
241+
link-options = [""] # linker flags
241242
private-link-options = [""]
242-
precompile-headers = [""]
243+
precompile-headers = [""] # precompiled headers
243244
private-precompile-headers = [""]
244245

245246
cmake-before = """
@@ -258,6 +259,35 @@ CXX_STANDARD_REQUIRED = true
258259
FOLDER = "MyFolder"
259260
```
260261

262+
A table mapping the cmkr features to the relevant CMake construct and the relevant documentation pages:
263+
264+
| cmkr | CMake construct | Description |
265+
| ---- | ----- | ----------- |
266+
| `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. |
267+
| `sources` | [`target_sources`](https://cmake.org/cmake/help/latest/command/target_sources.html) | Source files (`PRIVATE` except `interface` targets). |
268+
| `headers` | [`target_sources`](https://cmake.org/cmake/help/latest/command/target_sources.html) | For readability (and future packaging). |
269+
| `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. |
270+
| `compile-definitions` | [`target_compile_definitions`](https://cmake.org/cmake/help/latest/command/target_compile_definitions.html) | Adds a macro definition (define, `-DMYMACRO=XXX`). |
271+
| `compile-features` | [`target_compile_features`](https://cmake.org/cmake/help/latest/command/target_compile_features.html) | Specifies the C++ standard version (`cxx_std_20`). |
272+
| `compile-options` | [`target_compile_options`](https://cmake.org/cmake/help/latest/command/target_compile_options.html) | Adds compiler flags. |
273+
| `include-directories` | [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) | Adds include directories. |
274+
| `link-directories` | [`target_link_directories`](https://cmake.org/cmake/help/latest/command/target_link_directories.html) | Adds library directories. |
275+
| `link-libraries` | [`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) | Adds library dependencies. |
276+
| `link-options` | [`target_link_options`](https://cmake.org/cmake/help/latest/command/target_link_options.html) | Adds linker flags. |
277+
| `precompile-headers` | [`target_precompile_headers`](https://cmake.org/cmake/help/latest/command/target_precompile_headers.html) | Specifies precompiled headers. |
278+
| `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. |
279+
280+
The default [visibility](/basics) is as follows:
281+
282+
| Type | Visibility |
283+
| ------------ | ----------- |
284+
| `executable` | `PRIVATE` |
285+
| `library` | `PUBLIC` |
286+
| `shared` | `PUBLIC` |
287+
| `static` | `PUBLIC` |
288+
| `object` | `PUBLIC` |
289+
| `interface` | `INTERFACE` |
290+
261291
## Templates
262292

263293
To avoid repeating yourself you can create your own target type and use it in your targets:

docs/examples/compile-options.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ nav_order: 9
99

1010
# Compiler flags
1111

12-
Example project that sets compiler/linker flags for various platforms.
12+
Example project that sets compiler flags and preprocessor defines for various platforms.
1313

1414
```toml
1515
[project]
@@ -20,11 +20,14 @@ description = "Compiler flags"
2020
type = "executable"
2121
sources = ["src/main.cpp"]
2222
msvc.compile-options = ["/W2"]
23+
msvc.compile-definitions = ["PLATFORM=\"msvc\""]
2324
gcc.compile-options = ["-Wall"]
25+
gcc.compile-definitions = ["PLATFORM=\"gcc\""]
2426
clang.compile-options = ["-Wall"]
27+
clang.compile-definitions = ["PLATFORM=\"clang\""]
2528
```
2629

27-
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.
30+
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.
2831

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

docs/examples/vcpkg.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,20 @@ nav_order: 4
99

1010
# Dependencies from vcpkg
1111

12-
Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://vcpkg.io/) and links an `example` target to it:
12+
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:
1313

1414
```toml
1515
[project]
1616
name = "vcpkg"
1717
description = "Dependencies from vcpkg"
1818

1919
# See https://github.com/microsoft/vcpkg/releases for vcpkg versions
20-
# See https://vcpkg.io/en/packages.html for available packages
20+
# See https://vcpkg.io/en/packages or https://vcpkg.link for available packages
2121
[vcpkg]
22-
version = "2024.03.25"
22+
version = "2024.11.16"
2323
packages = ["fmt"]
2424

25-
[find-package]
26-
fmt = {}
25+
[find-package.fmt]
2726

2827
[target.example]
2928
type = "executable"

include/project_parser.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ struct Vcpkg {
4949
};
5050

5151
std::vector<Package> packages;
52+
53+
// https://github.com/Microsoft/vcpkg-docs/blob/main/vcpkg/users/buildsystems/cmake-integration.md
5254
std::vector<std::string> overlay_ports;
55+
std::vector<std::string> overlay_triplets;
5356

5457
bool enabled() const {
5558
return !packages.empty();

src/cmake_generator.cpp

+17-23
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,22 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
861861
endl();
862862
}
863863

864+
if (project.vcpkg.enabled()) {
865+
comment("vcpkg settings");
866+
auto emit_overlay = [&cmd](const std::string &name, const std::vector<std::string> &overlay) {
867+
if (!overlay.empty()) {
868+
for (const auto &directory : overlay) {
869+
if (!fs::is_directory(directory)) {
870+
throw std::runtime_error("[vcpkg] overlay is not a directory: " + directory);
871+
}
872+
}
873+
cmd("set")(name, overlay);
874+
}
875+
};
876+
emit_overlay("VCPKG_OVERLAY_PORTS", project.vcpkg.overlay_ports);
877+
emit_overlay("VCPKG_OVERLAY_TRIPLETS", project.vcpkg.overlay_triplets);
878+
}
879+
864880
gen.conditional_includes(project.include_before);
865881
gen.conditional_cmake(project.cmake_before);
866882

@@ -996,29 +1012,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
9961012
ofs << " ],\n";
9971013
ofs << " \"description\": \"" << escape(project.project_description) << "\",\n";
9981014
ofs << " \"name\": \"" << escape(vcpkg_escape_identifier(project.project_name)) << "\",\n";
999-
ofs << " \"version-string\": \"none\"";
1000-
const auto &overlay_ports = project.vcpkg.overlay_ports;
1001-
if (!overlay_ports.empty()) {
1002-
ofs << ",\n";
1003-
// Reference: https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json#vcpkg-configuration
1004-
ofs << " \"vcpkg-configuration\": {\n";
1005-
ofs << " \"overlay-ports\": [\n";
1006-
for (size_t i = 0; i < overlay_ports.size(); i++) {
1007-
const auto &directory = overlay_ports[i];
1008-
if (!fs::is_directory(directory)) {
1009-
throw std::runtime_error("[vcpkg].overlay-ports is not a directory: " + directory);
1010-
}
1011-
ofs << " \"" << escape(directory) << "\"";
1012-
if (i > 0) {
1013-
ofs << ",";
1014-
}
1015-
ofs << "\n";
1016-
}
1017-
ofs << " ]\n";
1018-
ofs << " }\n";
1019-
} else {
1020-
ofs << "\n";
1021-
}
1015+
ofs << " \"version-string\": \"none\"\n";
10221016
ofs << "}\n";
10231017
}
10241018

src/project_parser.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,20 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p
860860
vcpkg.packages.emplace_back(std::move(package));
861861
}
862862

863-
v.optional("overlay-ports", vcpkg.overlay_ports);
863+
if (v.contains("overlay")) {
864+
std::string overlay;
865+
v.optional("overlay", overlay);
866+
vcpkg.overlay_triplets = vcpkg.overlay_ports = {overlay};
867+
if (v.contains("overlay-ports")) {
868+
throw_key_error("[vcpkg].overlay was already specified", "overlay-ports", v.find("overlay-ports"));
869+
}
870+
if (v.contains("overlay-triplets")) {
871+
throw_key_error("[vcpkg].overlay was already specified", "overlay-triplets", v.find("overlay-triplets"));
872+
}
873+
} else {
874+
v.optional("overlay-ports", vcpkg.overlay_ports);
875+
v.optional("overlay-triplets", vcpkg.overlay_triplets);
876+
}
864877
}
865878

866879
checker.check(conditions, true);

tests/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# These will be generated by cmkr, so no point in tracking them
22
**/CMakeLists.txt
3-
**/cmkr.cmake
3+
**/cmkr.cmake
4+
**/vcpkg.json

tests/compile-options/cmake.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Example project that sets compiler/linker flags for various platforms.
1+
# Example project that sets compiler flags and preprocessor defines for various platforms.
22

33
[project]
44
name = "compile-options"
@@ -8,8 +8,11 @@ description = "Compiler flags"
88
type = "executable"
99
sources = ["src/main.cpp"]
1010
msvc.compile-options = ["/W2"]
11+
msvc.compile-definitions = ["PLATFORM=\"msvc\""]
1112
gcc.compile-options = ["-Wall"]
13+
gcc.compile-definitions = ["PLATFORM=\"gcc\""]
1214
clang.compile-options = ["-Wall"]
15+
clang.compile-definitions = ["PLATFORM=\"clang\""]
1316

14-
# 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.
17+
# 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.
1518
# _Note_: In general you only want to specify flags _required_ to compile your code without errors.

tests/vcpkg/cmake.toml

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
# Downloads [fmt v7.1.3](https://fmt.dev/7.1.3/) using [vcpkg](https://vcpkg.io/) and links an `example` target to it:
1+
# 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:
22

33
[project]
44
name = "vcpkg"
55
description = "Dependencies from vcpkg"
66

77
# See https://github.com/microsoft/vcpkg/releases for vcpkg versions
8-
# See https://vcpkg.io/en/packages.html for available packages
8+
# See https://vcpkg.io/en/packages or https://vcpkg.link for available packages
99
[vcpkg]
10-
version = "2024.03.25"
10+
version = "2024.11.16"
1111
packages = ["fmt"]
1212

13-
[find-package]
14-
fmt = {}
13+
[find-package.fmt]
1514

1615
[target.example]
1716
type = "executable"

tests/vcpkg/vcpkg.json

-11
This file was deleted.

0 commit comments

Comments
 (0)