Skip to content

fix: ensure installed binaries have executable permissions#1233

Open
ANAS727189 wants to merge 2 commits intofortran-lang:mainfrom
ANAS727189:file-perm-fix
Open

fix: ensure installed binaries have executable permissions#1233
ANAS727189 wants to merge 2 commits intofortran-lang:mainfrom
ANAS727189:file-perm-fix

Conversation

@ANAS727189
Copy link

Fixes #314

This PR fixes an issue where binaries installed via fpm install (or ./install.sh) did not have the executable bit set (resulting in rw-r--r--), requiring users to manually run chmod +x.

Changes Implemented

  • src/fpm_filesystem.F90: Added a set_executable subroutine.
  • It uses c_chmod (via iso_c_binding) for standard builds (efficient and standard).
  • Includes a fallback to shell chmod +x for the bootstrap phase (#ifdef FPM_BOOTSTRAP).
  • Includes an os_is_unix() check to ensure it only runs on relevant platforms (no-op on Windows).

Testing
Created a new project (fpm new test_perms), installed it, and verified via ls -l that the resulting binary in ~/.local/bin (or prefix) has -rwxr-xr-x permissions.

test_perms [ master][?][🅵  9.4.0][🅒 lf]
❯ fpm install --prefix ./inst
 + mkdir -p build/dependencies
test_perms.f90                         done.
libtest_perms.a                        done.
main.f90                               done.
test_perms                             done.
[100%] Project compiled successfully.
 + mkdir -p ./inst/bin
# Update: build/gfortran_A86CEF2075723C1E/app/test_perms -> ./inst/bin

test_perms [ master][?][🅵  9.4.0][🅒 lf]
❯ ls -l inst/bin/test_perms
-rwxr-xr-x 1 anas anas 16912 Jan 22 17:42 inst/bin/test_perms
  • Regression Testing: Ran the full test suite via fpm test. All 35 tests PASSED.

Copilot AI review requested due to automatic review settings January 22, 2026 12:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where binaries installed via fpm install did not have executable permissions set, requiring users to manually run chmod +x. The fix adds a new set_executable function that uses the C chmod function for efficiency on Unix systems, with a fallback to shell commands during bootstrap, and skips the operation on Windows.

Changes:

  • Added set_executable subroutine in fpm_filesystem.F90 that sets executable permissions (755) on Unix systems
  • Modified install_executable in installer.f90 to call set_executable after installation
  • Optimized exe_path calculation to avoid duplication for macOS rpath operations

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/fpm_filesystem.F90 Adds new set_executable subroutine with C binding to chmod for non-bootstrap builds and shell fallback for bootstrap
src/fpm/installer.f90 Calls set_executable after installing executables and reuses exe_path variable for macOS rpath commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

end if
#else
! Fallback using shell command
call run("chmod +x " // filename, echo=.false., verbose=.false., exitstat=stat)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The bootstrap fallback path silently ignores chmod failures by not checking the exitstat value. While a warning is logged in the non-bootstrap path when chmod fails, the bootstrap path should also handle failures consistently. Consider checking the stat variable and logging a warning if the command fails.

Suggested change
call run("chmod +x " // filename, echo=.false., verbose=.false., exitstat=stat)
call run("chmod +x " // filename, echo=.false., verbose=.false., exitstat=stat)
if (stat /= 0) then
write(stderr, *) "Warning: Failed to set executable permissions on: ", filename
end if

Copilot uses AI. Check for mistakes.
Comment on lines 1266 to 1284
subroutine set_executable(filename)
character(len=*), intent(in) :: filename
integer :: stat

if (.not. os_is_unix()) return

#ifndef FPM_BOOTSTRAP
! Use C library chmod (faster, standard)
! o'755' is octal for rwxr-xr-x
stat = c_chmod(filename // c_null_char, int(o'755', c_int))
if (stat /= 0) then
write(stderr, *) "Warning: Failed to set executable permissions on: ", filename
end if
#else
! Fallback using shell command
call run("chmod +x " // filename, echo=.false., verbose=.false., exitstat=stat)
#endif

end subroutine set_executable
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The new set_executable function lacks test coverage. Since the repository has a test_filesystem.f90 file with tests for other filesystem functions, consider adding a test to verify that executable permissions are correctly set on Unix systems and that the function is a no-op on Windows.

Copilot uses AI. Check for mistakes.
add_rpath: if (self%os==OS_MACOS) then

exe_path = join_path(self%install_destination(self%bindir) , basename(executable))
! exe_path is already calculated above
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The comment is misleading because it suggests the removed line was incorrect or unnecessary, when in reality it was moved earlier for efficiency. Consider clarifying this as "Reused from above" or simply removing the comment since the code is self-explanatory.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow file permissions for fpm-install

1 participant