From 7d35bcac011beddb10d6ba586eff3f665afcb9b9 Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Thu, 8 Jan 2026 16:34:19 +0900 Subject: [PATCH 1/3] Add --output-dir option to generate_C_API.jl - Add --output-dir command-line option to specify output directory - Improve argument parsing to handle multiple options correctly - Allow generating C_API.jl to a custom location (useful for build scripts) --- CalcPi.jl/utils/generate_C_API.jl | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/CalcPi.jl/utils/generate_C_API.jl b/CalcPi.jl/utils/generate_C_API.jl index 735270d..3626962 100644 --- a/CalcPi.jl/utils/generate_C_API.jl +++ b/CalcPi.jl/utils/generate_C_API.jl @@ -11,17 +11,23 @@ function print_help() println() println("Options:") println(" --calcpi-rs-dir PATH Specify the calcpi-rs directory path") + println(" --output-dir PATH Specify the output directory for C_API.jl") println(" --help, -h Show this help message") println() println("Examples:") println(" julia generate_C_API.jl --calcpi-rs-dir /path/to/calcpi-rs") + println(" julia generate_C_API.jl --output-dir /path/to/output") println() println("Default: Uses ../deps/calcpi-rs relative to this script") + println(" Output goes to ../src/C_API.jl relative to this script") end # Parse command line arguments calcpi_rs_dir = nothing -for (i, arg) in enumerate(ARGS) +output_dir = nothing +i = 1 +while i <= length(ARGS) + arg = ARGS[i] if arg == "--help" || arg == "-h" print_help() exit(0) @@ -29,10 +35,22 @@ for (i, arg) in enumerate(ARGS) if i + 1 <= length(ARGS) global calcpi_rs_dir calcpi_rs_dir = ARGS[i + 1] + i += 2 else println("Error: --calcpi-rs-dir requires a path argument") exit(1) end + elseif arg == "--output-dir" + if i + 1 <= length(ARGS) + global output_dir + output_dir = ARGS[i + 1] + i += 2 + else + println("Error: --output-dir requires a path argument") + exit(1) + end + else + i += 1 end end @@ -74,6 +92,16 @@ else options = Dict{String,Any}() end +# Override output path if specified +if output_dir !== nothing + output_dir = normpath(abspath(output_dir)) + if !isdir(output_dir) + mkpath(output_dir) + end + options["output_file_path"] = joinpath(output_dir, "C_API.jl") + println("Output directory: $output_dir") +end + # add compiler flags, e.g. "-DXXXXXXXXX" args = get_default_args() push!(args, "-I$include_dir") From f352a32b212b411423ff3bcd023b4f02908d5c29 Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Thu, 8 Jan 2026 16:34:22 +0900 Subject: [PATCH 2/3] Fix Permission denied error when building installed packages - Generate C_API.jl in temporary directory first - Copy to src/ only if writable (development environment) - Handle read-only src/ gracefully for installed packages - Prevents build failures when package is installed via Pkg.add() --- CalcPi.jl/deps/build.jl | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/CalcPi.jl/deps/build.jl b/CalcPi.jl/deps/build.jl index bb05556..8133b04 100644 --- a/CalcPi.jl/deps/build.jl +++ b/CalcPi.jl/deps/build.jl @@ -24,16 +24,37 @@ if isdir(DEV_DIR) # Always copy to libcalcpi_rs. in deps/ for consistency cp(libcalcpi_path, joinpath(@__DIR__, "libcalcpi_rs.$(dlext)"); force=true) - cd(joinpath(dirname(@__DIR__), "utils")) do - run(`$(Base.julia_cmd()) --project generate_C_API.jl`) + # Generate C_API.jl in a temporary directory first, then copy to the appropriate location + # This handles the case where the package is installed and src/ is read-only + package_dir = dirname(@__DIR__) + src_dir = joinpath(package_dir, "src") + temp_output_dir = mktempdir() + + cd(joinpath(package_dir, "utils")) do + run(`$(Base.julia_cmd()) --project generate_C_API.jl --output-dir $temp_output_dir`) end - # Remove CEnum import if not needed (post-processing) - c_api_path = joinpath(dirname(@__DIR__), "src", "C_API.jl") - if isfile(c_api_path) - content = read(c_api_path, String) - # Remove CEnum import if present - content = replace(content, r"using CEnum: CEnum, @cenum\n\n" => "") - write(c_api_path, content) + # Copy generated file to src/ if writable + temp_c_api_path = joinpath(temp_output_dir, "C_API.jl") + if isfile(temp_c_api_path) + c_api_path = joinpath(src_dir, "C_API.jl") + # Check if src/ is writable by testing write access + try + content = read(temp_c_api_path, String) + # Remove CEnum import if not needed (post-processing) + content = replace(content, r"using CEnum: CEnum, @cenum\n\n" => "") + # Try to write to src/ + open(c_api_path, "w") do f + write(f, content) + end + println("Generated C_API.jl in src/") + catch e + # If src/ is read-only (e.g., installed package), skip writing + # The existing C_API.jl in the package should be used + println("Warning: Cannot write to src/ (package may be installed). Using existing C_API.jl.") + end + rm(temp_output_dir; recursive=true) + else + error("Failed to generate C_API.jl") end end From 4dee79c81f19848854ba4f81197b058598f0663a Mon Sep 17 00:00:00 2001 From: Satoshi Terasaki Date: Thu, 8 Jan 2026 16:34:25 +0900 Subject: [PATCH 3/3] Add test script for package installation and testing - Add run.sh script to test package installation from GitHub - Useful for verifying that Pkg.add() and Pkg.test() work correctly --- run.sh | 1 + 1 file changed, 1 insertion(+) create mode 100644 run.sh diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..595f865 --- /dev/null +++ b/run.sh @@ -0,0 +1 @@ +julia -e 'using Pkg; Pkg.activate(temp=true); Pkg.add(url="git@github.com:AtelierArith/RustToolChainExamples.jl.git", subdir="CalcPi.jl"); Pkg.test("CalcPi")' \ No newline at end of file