Skip to content
Closed
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
10 changes: 7 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"hostRequirements": {
"cpus": 4
},
"runArgs": [
"--cap-add=SYS_PTRACE"
],
"customizations": {
"vscode": {
"settings": {
Expand All @@ -12,8 +15,8 @@
"editor.detectIndentation": false,
"r.lsp.diagnostics": false,
"r.plot.useHttpgd": true,
"r.rterm.linux": "/workspaces/r-dev-env/scripts/launch_r.sh",
"r.rpath.linux": "/usr/bin/R",
"r.rterm.linux": "/usr/bin/R",
"terminal.integrated.sendKeybindingsToShell": true,
"svn.multipleFolders.enabled": true,
"workbench.editorAssociations": {
Expand All @@ -28,9 +31,10 @@
"johnstoncode.svn-scm",
"ms-vscode.cpptools",
"MS-vsliveshare.vsliveshare",
"natqe.reload"
"natqe.reload",
"vadimcn.vscode-lldb"
]
}
},
"postCreateCommand": "find . -wholename '*.git*' -type d -prune -o -type f -exec chown vscode:vscode {} \\; && sh /workspaces/r-dev-env/scripts/localscript.sh"
"postCreateCommand": "find . -wholename '.git*' -type d -prune -o -type f -exec chown vscode:vscode {} \\; && sh ./scripts/localscript.sh"
}
12 changes: 12 additions & 0 deletions .devcontainer/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Attach to R",
"type": "lldb",
"request": "attach",
"pid": "${command:pickMyProcess}",
"stopOnEntry": false
}
]
}
25 changes: 20 additions & 5 deletions docs/tutorials/building_r.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,22 @@ mkdir -p $BUILDDIR
cd $BUILDDIR
```

**5) Configure the build**
**5) Set CFLAGS (Optional—For Debugging C Code)**

- **This step is optional and recommended for those who want to debug C code.**
- Set the `CFLAGS` environment variable before running configure:

```bash
CFLAGS="-g -O0"
```

- These flags modify the configuration defined in the next step,
so that when R is built, C code will be compiled with debugging
symbols (`-g`) and compiler optimizations will be disabled
(`-O0`) so that the structure of the code closely matches the
original source.

**6) Configure the build**

- After we change directory, we must run the configure script from the source
directory. This step takes ~1 minute on the codespace.
Expand All @@ -80,7 +95,7 @@ $TOP_SRCDIR/configure --with-valgrind-instrumentation=1

![alt text](../assets/rdev7.png)

**6) Build R**
**7) Build R**

Having configured R, we run `make` to build R. This take 5-10 minutes on the
codespace.
Expand All @@ -89,7 +104,7 @@ codespace.
make
```

**7) Check R**
**8) Check R**

Check that the build of R passes R's standard checks:

Expand All @@ -101,7 +116,7 @@ This takes a couple of minutes in the codespace. The check will stop with a
error message if any of the tests fail. If this happens, see [SVN
Help](./svn_help.md) for how to revert to a version that passes check.

**8) Make R terminals use the built R**
**9) Make R terminals use the built R**

Run the `which_r` script to set which R to use for R terminals in VSCode. When
prompted, enter the number corresponding to `r-devel`
Expand All @@ -125,7 +140,7 @@ built![^1]
selected version is saved in the VSCode settings, so will be saved when you stop
and restart the codespace.

**9) Make contributions**
**10) Make contributions**

- After having built the current development version of R, we can now make
changes to the source code and contribute to the project.
Expand Down
6 changes: 6 additions & 0 deletions scripts/allow_ptrace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <sys/prctl.h>

__attribute__((constructor))
static void allow_ptrace(void) {
prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
}
Binary file added scripts/allow_ptrace.so
Binary file not shown.
3 changes: 3 additions & 0 deletions scripts/launch_r.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
export LD_PRELOAD=/workspaces/r-dev-env/scripts/allow_ptrace.so
exec /usr/bin/R "$@"
14 changes: 10 additions & 4 deletions scripts/localscript.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ local_script(){
WORK_DIR=$PWD
VSCODE_DIR="$WORK_DIR/.vscode"
DEVCONTAINER_JSON="$WORK_DIR/.devcontainer/devcontainer.json"
SCRIPTS_DIR="$WORK_DIR/scripts"

# Create patch directory in workspace root ($PWD at start)
PATCHDIR="$WORK_DIR/patches"
mkdir -p $PATCHDIR
mkdir -p $VSCODE_DIR

# Copy the which_r and set_build_r function definitions to .bashrc
cat $WORK_DIR/scripts/which_r.sh >> ~/.bashrc
cat $WORK_DIR/scripts/set_build_r.sh >> ~/.bashrc
cat $SCRIPTS_DIR/which_r.sh >> ~/.bashrc
cat $SCRIPTS_DIR/set_build_r.sh >> ~/.bashrc

# Copy over the welcome message script to be run when bash terminal starts
cat $WORK_DIR/scripts/welcome_msg.sh >> ~/.bashrc
cat $SCRIPTS_DIR/welcome_msg.sh >> ~/.bashrc

#bash ~/.bashrc

# Remove git directory if it exists
rm -rf .git

Expand All @@ -38,3 +38,9 @@ fi

# Run the main function
local_script

# 1. Build the ptrace helper library
gcc -shared -fPIC -o "$SCRIPTS_DIR/allow_ptrace.so" "$SCRIPTS_DIR/allow_ptrace.c"

# 2. Mark the wrapper executable
chmod +x "$SCRIPTS_DIR/launch_r.sh"
81 changes: 33 additions & 48 deletions scripts/which_r.sh
Original file line number Diff line number Diff line change
@@ -1,68 +1,53 @@

#!/usr/bin/env bash

which_r() {
# Specify the parent directory
parent_dir="$WORK_DIR/build"

# Path to the settings.json file
settings_file_path=$WORK_DIR/.vscode/settings.json
parent_dir="$PWD/build"
settings_file_path="$PWD/.vscode/settings.json"
launch_script="$PWD/scripts/launch_r.sh"

built_in_r_version=$(R --version | grep "^R version" | awk '{print $3}')
built_in_r_version=$(R --version | awk '/^R version/ {print $3}')

# Ask user which R version to use
echo "Which version of R should be used in new R terminals?"
echo " 1. R $built_in_r_version (release version built into this container)"
echo " 1. R $built_in_r_version (built-in)"

# Check for additional R versions in subdirectories
# Detect additional R builds
subdirs=()
counter=2
if [ -d "$parent_dir" ]; then
# Create an array to store subdirectory names
subdirs=()

# Loop through subdirectories and print numbered list
counter=2 # Start counter at 2 to avoid conflict with built-in R
for dir in "$parent_dir"/*; do
if [ -d "$dir/bin" ] && [ -x "$dir/bin/R" ]; then
subdir=$(basename "$dir")
subdirs+=("$subdir") # Populate subdirs array
echo " $counter. $subdir"
if [ -x "$dir/bin/R" ]; then
subdirs+=("$(basename "$dir")")
echo " $counter. ${subdirs[-1]}"
((counter++))
fi
done
fi

# If no additional R builds were found
if [ ${#subdirs[@]} -eq 0 ]; then
range=1
echo "No additional R builds available."
else
range=$((counter - 1))
fi
range=$((counter - 1))
[ "${#subdirs[@]}" -eq 0 ] && echo "No additional R builds found."

# Get user choice
read -p "Enter the number corresponding to the selected version: " choice
read -p "Enter number (1–$range): " choice

# Define selected version based on choice
if [[ "$choice" -eq 1 ]]; then
# Use built-in R
selected_version="/usr/bin/R"
elif [[ "$choice" -ge 2 ]] && [[ "$choice" -lt "$counter" ]]; then
# Use R from chosen subdirectory
chosen_subdir="${subdirs[((choice - 2))]}"
selected_version="$parent_dir/$chosen_subdir/bin/R"
if [ "$choice" -eq 1 ] 2>/dev/null; then
selected="/usr/bin/R"
elif [ "$choice" -ge 2 ] && [ "$choice" -le "$range" ] 2>/dev/null; then
idx=$((choice - 2))
selected="$parent_dir/${subdirs[$idx]}/bin/R"
else
# Invalid choice, default to built-in R
if [[ $range -eq 1 ]]; then
echo "Invalid choice, please enter 1. Defaulting to built-in R version."
else
echo "Invalid choice, please select options between 1 to $range. Defaulting to built-in R version."
fi
selected_version="/usr/bin/R"
echo "Invalid choice; defaulting to built-in"
selected="/usr/bin/R"
fi

# Update settings.json with the chosen R path
updated_settings_data=$(cat "$settings_file_path" | jq --arg subdir "$selected_version" '."r.rterm.linux"=$subdir | ."r.rpath.linux"=$subdir')
echo "$updated_settings_data" > "$settings_file_path"
# Update launch_r.sh to call the selected R
sed -i "s|^exec .*/R|exec $selected|" "$launch_script"

# Update VS Code setting if it exists
if [ -f "$settings_file_path" ]; then
jq --arg r "$selected" '."r.rpath.linux"=$r' \
"$settings_file_path" > "${settings_file_path}.tmp" \
&& mv "${settings_file_path}.tmp" "$settings_file_path"
fi

echo "R terminal will now use version: $selected_version"
echo "To update the HTML help, click \"Reload\" in the VS Code status bar (bottom right) to reload your VS Code window."
echo "Now using R at: $selected"
echo "Reload VS Code to apply updates."
}