Skip to content

Commit

Permalink
Merge pull request #46 from wravery/dev
Browse files Browse the repository at this point in the history
chore: update docs and export-cef-dir utility for next crates.io release
  • Loading branch information
wravery authored Feb 7, 2025
2 parents 58239a5 + 2ab930b commit 2776184
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 569 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 36 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,67 +11,67 @@ Use CEF in Rust.

## Usage

### Linux
### Install Shared CEF Binaries

#### Manual Install
This step is optional, but it will make all other builds of the `cef` crate much faster. If you don't do this, the `cef-dll-sys` crate `build.rs` script will download and extract the same files under its `OUT_DIR` directory. You should repeat this step each time you upgrade to a new version of the `cef` crate.

- [Download](https://cef-builds.spotifycdn.com/index.html#linux64) Linux-64bit build.
#### Linux or macOS:

- Copy files to `.local`:

```cmd
cp -r Resources ~/.local/share/cef
cp -r Release ~/.local/share/cef
```sh
cargo run -p export-cef-dir -- --force $HOME/.local/share/cef
```

- Build and run the application with `LD_LIBRARY_PATH` (or you can also add rpath to your cargo config or build script):
#### Windows (using PowerShell)

```cmd
LD_LIBRARY_PATH=~/.local/share/cef cargo r --example demo
```pwsh
cargo run -p export-cef-dir -- --force $env:USERPROFILE/.local/share/cef
```

#### Flatpak
### Set Environment Variables

- Install flatpak runtime & sdk:
#### Linux

```cmd
flatpak install flathub dev.crabnebula.Platform
flatpak install flathub dev.crabnebula.Sdk
```sh
export CEF_PATH=$HOME/.local/share/cef
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.local/share/cef
```

- Setup cargo project for flatpak. See [flatpak-builder-tools](https://github.com/flatpak/flatpak-builder-tools/blob/master/cargo/README.md) for more details. Here are files you will need to have at leaset:
- flatpak-cargo-generator.py
- flatpak manifest file (ie. app.example.demo.yml)
#### macOS

```sh
export CEF_PATH=$HOME/.local/share/cef
export DYLD_FALLBACK_LIBRARY_PATH=$DYLD_FALLBACK_LIBRARY_PATH:$HOME/.local/share/cef
```

- Build the flatpak application and run:
#### Windows (using PowerShell)

```cmd
cargo b --example demo
python3 ./flatpak-cargo-generator.py ./Cargo.lock -o cargo-sources.json
touch run.sh
flatpak-builder --user --install --force-clean target app.example.demo.yml
flatpak run app.example.demo
```pwsh
$env:CEF_PATH=$env:USERPROFILE/.local/share/cef
$env:PATH=$env:PATH;$env:USERPROFILE/.local/share/cef
```

### macOS
### Run the `cefsimple` Example

- Download cef prebuilts with `update-bindings`, it should print out the extracted `CEF_PATH` on success.
#### Linux

```cmd
cargo run -p update-bindings --bindgen --download
```sh
cargo run --example cefsimple
```

- Build and run the cefsimple application

```cmd
export CEF_PATH=<path>
#### macOS

```sh
./cef/examples/cefsimple/bundle_script.rs
open target/debug/examples/cefsimple.app
```

#### Windows (using PowerShell)

```pwsh
cp ./cef/examples/cefsimple/win/cefsimple.exe.manifest ./target/debug/examples/
cargo run --example cefsimple
```

## Contributing

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

37 changes: 0 additions & 37 deletions app.example.demo.yml

This file was deleted.

20 changes: 20 additions & 0 deletions cef/examples/cefsimple/win/cefsimple.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<!--The compatibility section will be merged from build/win/compatibility.manifest -->

<dependency>
<dependentAssembly>
<assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
</dependentAssembly>
</dependency>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" />
</requestedPrivileges>
</security>
</trustInfo>

</assembly>
2 changes: 1 addition & 1 deletion cef/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! # cef-rs
//! # cef
//!
//! Use the [Chromium Embedded Framework](https://github.com/chromiumembedded/cef) in Rust.
Expand Down
2 changes: 1 addition & 1 deletion download-cef/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "download-cef"
description = "Download and extract pre-built CEF (Chromium Embedded Framework) archives."
version = "1.2.0"
version = "1.2.1"

edition.workspace = true
license.workspace = true
Expand Down
5 changes: 5 additions & 0 deletions download-cef/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! # download-cef
//!
//! Utility functions to download and extract prebuilt [Chromium Embedded Framework](https://github.com/chromiumembedded/cef)
//! archives on any supported platform.
use bzip2::bufread::BzDecoder;
use serde::{Deserialize, Serialize};
use sha1_smol::Sha1;
Expand Down
1 change: 0 additions & 1 deletion export-cef-dir/build.rs

This file was deleted.

110 changes: 68 additions & 42 deletions export-cef-dir/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
//! # export-cef-dir
//!
//! Export files from the prebuilt [Chromium Embedded Framework](https://github.com/chromiumembedded/cef)
//! archive on any supported platform. The structure of the exported directory matches the way that
//! the `cef-dll-sys` crate expects to see them.
//!
//! To use the target directory when building, set the `CEF_PATH` environment variable to the path of the
//! exported directory, e.g., `~/.local/share/cef`.
//!
//! To use the DLLs in this directory at runtime, the library loader path varies by platform:
//! - Linux
//! ```sh
//! export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$CEF_PATH"
//! ```
//! - macOS
//! ```sh
//! export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$CEF_PATH"
//! ```
//! - Windows (using PowerShell)
//! ```pwsh
//! $env:PATH = "$env:PATH;$env:CEF_PATH"
//! ```
use clap::Parser;
use download_cef::{CefIndex, OsAndArch};
use std::{
fs::{self, File},
io::{self, Write},
path::{Path, PathBuf},
io::Write,
path::PathBuf,
};

#[cfg(target_os = "windows")]
Expand All @@ -16,8 +39,10 @@ const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu";
#[derive(Parser, Debug)]
#[command(about, long_about = None)]
struct Args {
#[arg(short, long, default_value = "false")]
#[arg(short, long)]
force: bool,
#[arg(short, long)]
save_archive: bool,
#[arg(short, long, default_value = DEFAULT_TARGET)]
target: String,
output: String,
Expand All @@ -26,71 +51,72 @@ struct Args {
fn main() -> anyhow::Result<()> {
let args = Args::parse();
let output = PathBuf::from(args.output);
let parent = PathBuf::from(
output
.parent()
.ok_or_else(|| anyhow::anyhow!("invalid target directory: {}", output.display()))?,
);

if output.exists() {
if fs::exists(&output)? {
if !args.force {
return Err(anyhow::anyhow!(
"target directory already exists: {}",
output.display()
));
}

let parent = output.parent();
let dir = output
.file_name()
.and_then(|dir| dir.to_str())
.ok_or_else(|| anyhow::anyhow!("invalid target directory: {}", output.display()))?;
let old_output = parent.map(|p| p.join(format!("old_{dir}")));
let old_output = old_output.as_ref().unwrap_or(&output);
fs::rename(&output, old_output)?;
let old_output = parent.join(format!("old_{dir}"));
fs::rename(&output, &old_output)?;
println!("Cleaning up: {}", old_output.display());
fs::remove_dir_all(old_output)?
}

let target = args.target.as_str();
let os_arch = OsAndArch::try_from(target)?;
let out_dir = PathBuf::from(env!("OUT_DIR"));
let cef_dir = os_arch.to_string();
let cef_dir = out_dir.join(&cef_dir);
let cef_dir = parent.join(&cef_dir);

if !fs::exists(&cef_dir)? {
let cef_version = env!("CARGO_PKG_VERSION");
let index = CefIndex::download()?;
let platform = index.platform(target)?;
let version = platform.version(cef_version)?;
if fs::exists(&cef_dir)? {
let dir = cef_dir
.file_name()
.and_then(|dir| dir.to_str())
.ok_or_else(|| anyhow::anyhow!("invalid target directory: {}", output.display()))?;
let old_cef_dir = parent.join(format!("old_{dir}"));
fs::rename(&cef_dir, &old_cef_dir)?;
println!("Cleaning up: {}", old_cef_dir.display());
fs::remove_dir_all(old_cef_dir)?
}

let archive = version.download_archive(&out_dir, true)?;
let extracted_dir = download_cef::extract_target_archive(target, &archive, &out_dir, true)?;
if extracted_dir != cef_dir {
return Err(anyhow::anyhow!(
"extracted dir {extracted_dir:?} does not match cef_dir {cef_dir:?}",
));
}
let cef_version = env!("CARGO_PKG_VERSION");
let index = CefIndex::download()?;
let platform = index.platform(target)?;
let version = platform.version(cef_version)?;

let archive_version = serde_json::to_string_pretty(version.minimal()?)?;
let mut archive_json = File::create(extracted_dir.join("archive.json"))?;
archive_json.write_all(archive_version.as_bytes())?;
let archive = version.download_archive(&parent, true)?;
let extracted_dir = download_cef::extract_target_archive(target, &archive, &parent, true)?;
if extracted_dir != cef_dir {
return Err(anyhow::anyhow!(
"extracted dir {extracted_dir:?} does not match cef_dir {cef_dir:?}",
));
}

copy_directory(cef_dir, &output)?;
if !args.save_archive {
println!("Cleaning up: {}", archive.display());
fs::remove_file(archive)?;
}

Ok(())
}
let archive_version = serde_json::to_string_pretty(version.minimal()?)?;
let mut archive_json = File::create(extracted_dir.join("archive.json"))?;
archive_json.write_all(archive_version.as_bytes())?;

fn copy_directory<P, Q>(src: P, dst: Q) -> io::Result<()>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(&src)? {
let entry = entry?;
let dst_path = dst.as_ref().join(entry.file_name());
if entry.file_type()?.is_dir() {
copy_directory(&entry.path(), &dst_path)?;
} else {
fs::copy(&entry.path(), &dst_path)?;
}
if output != cef_dir {
println!("Renaming: {}", output.display());
fs::rename(cef_dir, output)?;
}

Ok(())
}
Loading

0 comments on commit 2776184

Please sign in to comment.