Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
695ba52
emsdk: added new recipe
perseoGI Jun 13, 2025
ac1c0d2
Merge branch 'main' into pgi/new/emsdk
czoido Jun 16, 2025
8f27571
wip
czoido Jun 16, 2025
12820bd
wip
czoido Jun 16, 2025
1768ae6
wip
czoido Jun 16, 2025
8bfa242
wip
czoido Jun 16, 2025
240b479
wip
czoido Jun 16, 2025
e01773a
wip
czoido Jun 16, 2025
4c44611
wip
perseoGI Jun 16, 2025
e62adda
Removed requirements
perseoGI Jun 17, 2025
334f376
try to fix output
czoido Jun 17, 2025
48823f6
Updated profiles, readme and ci
perseoGI Jun 17, 2025
06b9bd6
Updated CI, build only changed recipes
perseoGI Jun 17, 2025
43ab52f
Updated readme
perseoGI Jun 17, 2025
ecb363a
Moved general config to base CI profile
perseoGI Jun 19, 2025
fa69614
Fix error
perseoGI Jun 19, 2025
d08d241
Fix error
perseoGI Jun 19, 2025
44f11d9
Added user_toolchain example on native profile
perseoGI Jun 24, 2025
c080b28
Restore build_folder_vars
perseoGI Jun 25, 2025
81f7789
Added threads comment
perseoGI Jun 25, 2025
6ff3792
Removed unneded min node version
perseoGI Jun 25, 2025
c5746ce
Update requirements.txt
czoido Jul 1, 2025
3c475c9
Removed asmjs profile
perseoGI Jul 1, 2025
9736f29
Applied some review suggestions
perseoGI Jul 2, 2025
9ec67da
Removed unneded builddirs environment as already included by Emscript…
perseoGI Jul 3, 2025
073931e
Removed auto install conf in profile
perseoGI Jul 3, 2025
64ef64c
Restored original test_package and created test_example
perseoGI Jul 4, 2025
b1fe0cb
Fix ci
perseoGI Jul 4, 2025
6e335fb
Testing publish profiles workflow
perseoGI Jul 4, 2025
cbc1e53
WIP
perseoGI Jul 4, 2025
a5ed161
WIP
perseoGI Jul 4, 2025
c6aae81
Publish profiles
perseoGI Jul 4, 2025
dfe8b47
Publish profiles
perseoGI Jul 4, 2025
8dc22f5
Publish profiles
perseoGI Jul 4, 2025
92be15d
Publish profiles
perseoGI Jul 4, 2025
516d065
Removed support for multi versions in CI
perseoGI Jul 8, 2025
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
12 changes: 12 additions & 0 deletions .github/scripts/.ci_base_profile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include(default)

[conf]
tools.build.cross_building:can_run=True

# Verbosity
tools.build:verbosity=verbose
tools.compilation:verbosity=verbose

# Package Manager Configuration
*/system:tools.system.package_manager:mode=install
*/system:tools.system.package_manager:sudo=True
65 changes: 65 additions & 0 deletions .github/scripts/build_recipes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
import os
import json
from pathlib import Path
import subprocess
import yaml
from collections import defaultdict


def get_updated_recipes():
updated_paths = os.getenv("BUILD_RECIPES", "").split(" ")
recipe_files = defaultdict(set)
for path in updated_paths:
parts = Path(path).parts
if len(parts) >= 2 and parts[0] == "recipes":
recipe_name = parts[1]
file = "/".join(parts[2:])
recipe_files[recipe_name].add(file)
return set(recipe_files.keys())


def load_versions(recipe_dir: Path) -> dict:
cfg = recipe_dir / "config.yml"
if not cfg.is_file():
return {}
return yaml.safe_load(cfg.read_text() or "").get("versions", {})


for recipe_name in get_updated_recipes():
recipe_dir = Path("recipes") / recipe_name
versions = load_versions(recipe_dir)

for version, info in versions.items():
recipe_path = recipe_dir / info.get("folder", ".")

inspect_json = subprocess.check_output(
["conan", "inspect", str(recipe_path / "conanfile.py"), "--format=json"],
text=True,
)
recipe_name = json.loads(inspect_json)["name"]

cmd = [
"conan",
"create",
str(recipe_path),
"--version",
version,
"--build",
"missing",
"--build-test",
f"{recipe_name}/*",
"--build-require",
"-pr:h",
str(recipe_path / ".ci_profile"),
"-pr:a",
str(Path(__file__).parent / ".ci_base_profile"),
]

print(f"::group::{recipe_name}/{version}", flush=True)

try:
print("executing:", " ".join(cmd), flush=True)
subprocess.run(cmd, check=True)
finally:
print("::endgroup::", flush=True)
51 changes: 51 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Test all recipes

on:
push:
pull_request:
branches:
- main
workflow_dispatch:

jobs:
create:
name: Create and test Conan recipes
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install requirements
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Cache local Conan repo
uses: actions/cache@v3
with:
path: ~/.conan2/p
key: ${{ runner.os }}-conan2-${{ hashFiles('recipes/**') }}
restore-keys: |
${{ runner.os }}-conan2-

- name: Get changed recipes
id: changed-recipes
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46
with:
files: |
recipes/**
files_ignore: recipes/*.{md,txt}

- name: Build and test recipes
if: steps.changed-recipes.outputs.any_changed == 'true'
env:
BUILD_RECIPES: ${{ steps.changed-recipes.outputs.all_changed_files }}
run: |
conan profile detect
conan config install conan_config
python .github/scripts/build_recipes.py
35 changes: 21 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ utilities, for example the Emscripten SDK or other compilers. These recipes are
maintained independently of [Conan Center Index](https://github.com/conan-io/conan-center-index)
with flexible maintenance scopes.

---

## 🌟 Why a separate repo?

Expand All @@ -18,10 +17,25 @@ tailoring recipes as needed. It also supports bleeding-edge or niche toolchains
that don't belong in the main index, offering maximum flexibility and
control.

---
## 🧰 Built-in Profiles

This repository includes several **pre-configured Conan profiles** designed to make toolchain setup effortless:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each "toolchain" should have a readme with tailored instructions - as I would expect this grow in the future.
I would refer to them as "reference" profiles - the ones we test, leaving it up to users to customise before installing. e.g. the "native" one still requires manual configuration, so I'm not sure that's effortless, there's still some use intervention needed in some instances.

we may consider having the profile .zip files as releases - so that a user can do conan config install https://github.com/xxxx/emsdk_profiles_1.0.zip or something like that - so that they get only what they need

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this line, another approach would be to have the profiles in a specific folder, under the emsdk folder. Let the users manually copy them, or if not, they can do a conan config install --source-folder to specify the specific folder. But better that than a single conan config install that will bring different profiles for emcc, cuda, etc, etc, of different unrelated things that users will not want in general

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is another good approach, right now, what I've done in the CI is the ability to publish recipe specific profiles manually with a github action, check out my fork releases: https://github.com/perseoGI/conan-toolchains/releases

This can be installed with:

$ conan config install https://github.com/perseoGI/conan-toolchains/releases/download/emsdk-4.0.10-profiles.zip/emsdk-4.0.10-profiles.zip

Allowing profile isolation with different recipes, and also, keeping a profile versioning.

Do you like this approach?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seem a bit overkill to me, in terms of extra effort to publish and release the profiles, version them, etc.
One of the reasons of using the conan-toolchains repo is that it is not necessary to provide the same backward compatibility and previous versions support, and it is possible a more "live at head" approach. So such a strong effort towards versioning profiles seems very overkill to me.


To install the respective profiles:

```sh
$ conan config install https://github.com/conan-io/conan-toolchains.git -sf conan_config
```

Profiles could be later listed:
```sh
$ conan profile list
```
Toolchain profiles will be located under `<toolchain_name>/<profile>`.
Profiles starting with dot (`.`) are considered *base* which are used for other profiles and should not be used directly.

## 🚀 Getting started

## 🚀 Getting started

### Setup `conan-toolchains` as a [local recipe index](https://docs.conan.io/2/devops/devops_local_recipes_index.html#devops-local-recipes-index) repository

Expand All @@ -38,21 +52,14 @@ This repository is still under active development, and no Conan remote with pre-

## Contributing

We welcome and appreciate contributions to **conan-toolchains**!

If you wish to contribute to **conan-toolchains**, follow these steps to clone the repository
and install the required development dependencies.
We recommend using [pre-commit](https://pre-commit.com/) to enforce code style and formatting. To
activate the pre-commit hooks contributors could optionally run the following commands:

```
git clone [email protected]:conan-io/conan-toolchains.git
cd conan-toolchains
# Recommended: Setup your virtual environment before installing dependencies
# Setup your virtual environment before installing dependencies
pip install pre-commit
```

We use [pre-commit](https://pre-commit.com/) to enforce code style and formatting. To
activate the pre-commit hooks:

```
pre-commit install
```

Expand Down
24 changes: 24 additions & 0 deletions conan_config/profiles/emsdk/.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Note: To use a local emsdk installation use -pr:h <wasm32/wasm64/asmjs> -pr:h native

[settings]
build_type=Release
compiler=emcc
compiler.cppstd=17
compiler.libcxx=libc++
# Choose between both types of multithreading support (or none)
# compiler.threads=<posix|wasm_workers>
compiler.version=4.0.10
os=Emscripten

[tool_requires]
ninja/[*]

[conf]
tools.build:exelinkflags+=['-sALLOW_MEMORY_GROWTH=1']
tools.build:sharedlinkflags+=['-sALLOW_MEMORY_GROWTH=1']

# Set Ninja as default generator as it is faster and will avoid Windows issues
tools.cmake.cmaketoolchain:generator=Ninja
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"faster" is an opinionated statement - for fresh builds ("from scratch"), the different is not very significant: https://david.rothlis.net/ninja-benchmark/ (see fresh builds)

Ninja may be better for very large projects or for working on an existing build tree (iterative builds) - but I wouldn't go for a blanket statement - for the vast majority of Conan Center recipes, I'd say difference is small.

The "windows issue" I presume has to do with CMake choosing the visual studio generator by default even when the compiler is emcc?


# Distinguish between architectures
tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch']
4 changes: 4 additions & 0 deletions conan_config/profiles/emsdk/.emsdk_base
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include(./.base)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure I think its justified to have two files .emsdk_base and .base


[tool_requires]
emsdk/[*]
8 changes: 8 additions & 0 deletions conan_config/profiles/emsdk/asmjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include(./.emsdk_base)

[settings]
arch=asm.js

[conf]
tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB']
tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB']
15 changes: 15 additions & 0 deletions conan_config/profiles/emsdk/native
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[platform_tool_requires]
emsdk/4.0.10

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name "native" can be confusing because "native" usually means the "local cpu architecture".
I would probably go for another name.

This profile seems to assume that all these tools are discoverable in PATH, otherwise they won't work, other than perhaps in CMake.

Is there a case for adding a PATH in the [buildenv] section to point to the installation directory, in case it is not in the system PATH?

once again ,a README for this profiles may clarify these questions

[conf]
tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'}
# Add native Emscripten toolchain
# tools.cmake.cmaketoolchain:user_toolchain=["/path/to/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"]

[buildenv]
CC=emcc
CXX=em++
AR=emar
NM=emnm
RANLIB=emranlib
STRIP=emstrip
8 changes: 8 additions & 0 deletions conan_config/profiles/emsdk/wasm32
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include(./.emsdk_base)

[settings]
arch=wasm

[conf]
tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB']
tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB']
10 changes: 10 additions & 0 deletions conan_config/profiles/emsdk/wasm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include(./.emsdk_base)

[settings]
arch=wasm64

[conf]
# In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution.
# wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory
tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS']
tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS']
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.ruff]
output-format = "full"
src = ["recipes"]
src = ["recipes", ".github/scripts"]
fix = true
show-fixes = true
line-length = 120
Expand Down
4 changes: 4 additions & 0 deletions recipes/emsdk/all/.ci_profile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include(emsdk/.base)

[settings]
arch=wasm
4 changes: 4 additions & 0 deletions recipes/emsdk/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources:
"4.0.10":
url: "https://github.com/emscripten-core/emsdk/archive/4.0.10.tar.gz"
sha256: "2497b55ddbba9bf9be2d18cfca3e973d40a0cfaa8d18f6caacb882a65b2faf1c"
Loading