8000 feat: added support for C++ files compilation by arteevraina · Pull Request #733 · fortran-lang/fpm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: added support for C++ files compilation #733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

8000
Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,9 @@ pushd preprocess_hello
"$fpm" build
popd

pushd cpp_files
"$fpm" test
popd

# Cleanup
rm -rf ./*/build
2 changes: 2 additions & 0 deletions example_packages/cpp_files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# cpp_files
My cool new project!
1 change: 1 addition & 0 deletions example_packages/cpp_files/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "cpp_files"
15 changes: 15 additions & 0 deletions example_packages/cpp_files/src/cpp_files.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module cpp_files
use, intrinsic :: ISO_C_Binding
implicit none
private

public :: intvec_maxval

interface
integer function intvec_maxval(array, n) bind(C, name = "intvec_maxval")
import :: c_int, c_size_t
integer(c_int), intent(in) :: array(*)
integer(c_size_t), intent(in), value :: n
end function intvec_maxval
end interface
end module cpp_files
14 changes: 14 additions & 0 deletions example_packages/cpp_files/src/hello_world.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <vector>
#include <algorithm>

extern "C" {

int intvec_maxval(int* array, size_t n){

std::vector<int> vec(array, array + n);

return *(std::max_element(vec.begin(), vec.end()));

}

}
18 changes: 18 additions & 0 deletions example_packages/cpp_files/test/check.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
program check
use iso_c_binding, only: c_size_t
use cpp_files
implicit none

integer :: i, max_element
integer, parameter :: array(*) = [(i,i=-50,10)]

max_element = intvec_maxval(array,size(array,1,c_size_t))

if (max_element == maxval(array)) then
write(*,*) ' PASSED: Max element is ',max_element
else
write(*,*) ' (!) FAILED: Incorrect max element returned'
stop 1
end if

end program check
8 changes: 6 additions & 2 deletions src/fpm.f90
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ subroutine build_model(model, settings, package, error)

integer :: i, j
type(package_config_t) :: dependency
character(len=:), allocatable :: manifest, lib_dir, flags, cflags, ldflags
character(len=:), allocatable :: manifest, lib_dir, flags, cflags, cxxflags, ldflags
character(len=:), allocatable :: version

logical :: duplicates_found = .false.
Expand All @@ -65,7 +65,7 @@ subroutine build_model(model, settings, package, error)
end if

call new_compiler(model%compiler, settings%compiler, settings%c_compiler, &
& echo=settings%verbose, verbose=settings%verbose)
& settings%cxx_compiler, echo=settings%verbose, verbose=settings%verbose)
call new_archiver(model%archiver, settings%archiver, &
& echo=settings%verbose, verbose=settings%verbose)

Expand All @@ -82,6 +82,7 @@ subroutine build_model(model, settings, package, error)
call set_preprocessor_flags(model%compiler%id, flags, package)

cflags = trim(settings%cflag)
cxxflags = trim(settings%cxxflag)
ldflags = trim(settings%ldflag)

if (model%compiler%is_unknown()) then
Expand All @@ -93,6 +94,7 @@ subroutine build_model(model, settings, package, error)

model%fortran_compile_flags = flags
model%c_compile_flags = cflags
model%cxx_compile_flags = cxxflags
model%link_flags = ldflags

model%include_tests = settings%build_tests
Expand Down Expand Up @@ -217,8 +219,10 @@ subroutine build_model(model, settings, package, error)
write(*,*)'<INFO> BUILD_NAME: ',model%build_prefix
write(*,*)'<INFO> COMPILER: ',model%compiler%fc
write(*,*)'<INFO> C COMPILER: ',model%compiler%cc
write(*,*)'<INFO> CXX COMPILER: ',model%compiler%cxx
write(*,*)'<INFO> COMPILER OPTIONS: ', model%fortran_compile_flags
write(*,*)'<INFO> C COMPILER OPTIONS: ', model%c_compile_flags
write(*,*)'<INFO> CXX COMPILER OPTIONS: ', model%cxx_compile_flags
write(*,*)'<INFO> LINKER OPTIONS: ', model%link_flags
write(*,*)'<INFO> INCLUDE DIRECTORIES: [', string_cat(model%include_dirs,','),']'
end if
Expand Down
7 changes: 6 additions & 1 deletion src/fpm_backend.F90
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module fpm_backend
use fpm_model, only: fpm_model_t
use fpm_strings, only: string_t, operator(.in.)
use fpm_targets, only: build_target_t, build_target_ptr, FPM_TARGET_OBJECT, &
FPM_TARGET_C_OBJECT, FPM_TARGET_ARCHIVE, FPM_TARGET_EXECUTABLE
FPM_TARGET_C_OBJECT, FPM_TARGET_ARCHIVE, FPM_TARGET_EXECUTABLE, &
FPM_TARGET_CPP_OBJECT
use fpm_backend_output
implicit none

Expand Down Expand Up @@ -323,6 +324,10 @@ subroutine build_target(model,target,verbose,stat)
call model%compiler%compile_c(target%source%file_name, target%output_file, &
& target%compile_flags, target%output_log_file, stat)

case (FPM_TARGET_CPP_OBJECT)
call model%compiler%compile_cpp(target%source%file_name, target%output_file, &
& target%compile_flags, target%output_log_file, stat)

case (FPM_TARGET_EXECUTABLE)
call model%compiler%link(target%output_file, &
& target%compile_flags//" "//target%link_flags, target%output_log_file, stat)
Expand Down
26 changes: 22 additions & 4 deletions src/fpm_command_line.f90
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ module fpm_command_line
logical :: prune=.true.
character(len=:),allocatable :: compiler
character(len=:),allocatable :: c_compiler
character(len=:),allocatable :: cxx_compiler
character(len=:),allocatable :: archiver
character(len=:),allocatable :: profile
character(len=:),allocatable :: flag
character(len=:),allocatable :: cflag
character(len=:),allocatable :: cxxflag
character(len=:),allocatable :: ldflag
end type

Expand Down Expand Up @@ -128,7 +130,7 @@ module fpm_command_line
& ' ', 'fpm', 'new', 'build', 'run', 'clean', &
& 'test', 'runner', 'install', 'update', 'list', 'help', 'version' ]

character(len=:), allocatable :: val_runner, val_compiler, val_flag, val_cflag, val_ldflag, &
character(len=:), allocatable :: val_runner, val_compiler, val_flag, val_cflag, val_cxxflag, val_ldflag, &
val_profile

! '12345678901234567890123456789012345678901234567890123456789012345678901234567890',&
Expand Down Expand Up @@ -197,11 +199,12 @@ subroutine get_command_line_settings(cmd_settings)
logical :: unix
type(fpm_install_settings), allocatable :: install_settings
character(len=:), allocatable :: common_args, compiler_args, run_args, working_dir, &
& c_compiler, archiver
& c_compiler, cxx_compiler, archiver

character(len=*), parameter :: fc_env = "FC", cc_env = "CC", ar_env = "AR", &
& fflags_env = "FFLAGS", cflags_env = "CFLAGS", ldflags_env = "LDFLAGS", &
& fc_default = "gfortran", cc_default = " ", ar_default = " ", flags_default = " "
& fflags_env = "FFLAGS", cflags_env = "CFLAGS", cxxflags_env = "CXXFLAGS", ldflags_env = "LDFLAGS", &
& fc_default = "gfortran", cc_default = " ", ar_default = " ", flags_default = " ", &
& cxx_env = "CXX", cxx_default = " "
type(error_t), allocatable :: error

call set_help()
Expand Down Expand Up @@ -245,9 +248,11 @@ subroutine get_command_line_settings(cmd_settings)
' --no-prune F' // &
' --compiler "'//get_fpm_env(fc_env, fc_default)//'"' // &
' --c-compiler "'//get_fpm_env(cc_env, cc_default)//'"' // &
' --cxx-compiler "'//get_fpm_env(cxx_env, cxx_default)//'"' // &
' --archiver "'//get_fpm_env(ar_env, ar_default)//'"' // &
' --flag:: "'//get_fpm_env(fflags_env, flags_default)//'"' // &
' --c-flag:: "'//get_fpm_env(cflags_env, flags_default)//'"' // &
' --cxx-flag:: "'//get_fpm_env(cxxflags_env, flags_default)//'"' // &
' --link-flag:: "'//get_fpm_env(ldflags_env, flags_default)//'"'

! now set subcommand-specific help text and process commandline
Expand Down Expand Up @@ -286,6 +291,7 @@ subroutine get_command_line_settings(cmd_settings)
enddo

c_compiler = sget('c-compiler')
cxx_compiler = sget('cxx-compiler')
archiver = sget('archiver')
allocate(fpm_run_settings :: cmd_settings)
val_runner=sget('runner')
Expand All @@ -296,9 +302,11 @@ subroutine get_command_line_settings(cmd_settings)
& prune=.not.lget('no-prune'), &
& compiler=val_compiler, &
& c_compiler=c_compiler, &
& cxx_compiler=cxx_compiler, &
& archiver=archiver, &
& flag=val_flag, &
& cflag=val_cflag, &
& cxxflag=val_cxxflag, &
& ldflag=val_ldflag, &
& example=lget('example'), &
& list=lget('list'),&
Expand All @@ -317,16 +325,19 @@ subroutine get_command_line_settings(cmd_settings)
call check_build_vals()

c_compiler = sget('c-compiler')
cxx_compiler = sget('cxx-compiler')
archiver = sget('archiver')
allocate( fpm_build_settings :: cmd_settings )
cmd_settings=fpm_build_settings( &
& profile=val_profile,&
& prune=.not.lget('no-prune'), &
& compiler=val_compiler, &
& c_compiler=c_compiler, &
& cxx_compiler=cxx_compiler, &
& archiver=archiver, &
& flag=val_flag, &
& cflag=val_cflag, &
& cxxflag=val_cxxflag, &
& ldflag=val_ldflag, &
& list=lget('list'),&
& show_model=lget('show-model'),&
Expand Down Expand Up @@ -470,6 +481,7 @@ subroutine get_command_line_settings(cmd_settings)
call check_build_vals()

c_compiler = sget('c-compiler')
cxx_compiler = sget('cxx-compiler')
archiver = sget('archiver')
allocate(install_settings)
install_settings = fpm_install_settings(&
Expand All @@ -478,9 +490,11 @@ subroutine get_command_line_settings(cmd_settings)
prune=.not.lget('no-prune'), &
compiler=val_compiler, &
c_compiler=c_compiler, &
cxx_compiler=cxx_compiler, &
archiver=archiver, &
flag=val_flag, &
cflag=val_cflag, &
cxxflag=val_cxxflag, &
ldflag=val_ldflag, &
no_rebuild=lget('no-rebuild'), &
verbose=lget('verbose'))
Expand Down Expand Up @@ -523,6 +537,7 @@ subroutine get_command_line_settings(cmd_settings)
enddo

c_compiler = sget('c-compiler')
cxx_compiler = sget('cxx-compiler')
archiver = sget('archiver')
allocate(fpm_test_settings :: cmd_settings)
val_runner=sget('runner')
Expand All @@ -533,9 +548,11 @@ subroutine get_command_line_settings(cmd_settings)
& prune=.not.lget('no-prune'), &
& compiler=val_compiler, &
& c_compiler=c_compiler, &
& cxx_compiler=cxx_compiler, &
& archiver=archiver, &
& flag=val_flag, &
& cflag=val_cflag, &
& cxxflag=val_cxxflag, &
& ldflag=val_ldflag, &
& example=.false., &
& list=lget('list'), &
Expand Down Expand Up @@ -616,6 +633,7 @@ subroutine check_build_vals()

val_flag = " " // sget('flag')
val_cflag = " " // sget('c-flag')
val_cxxflag = " "// sget('cxx-flag')
val_ldflag = " " // sget('link-flag')
val_profile = sget('profile')

Expand Down
67 changes: 66 additions & 1 deletion src/fpm_compiler.f90
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ module fpm_compiler
character(len=:), allocatable :: fc
!> Path to the C compiler
character(len=:), allocatable :: cc
!> Path to the C++ compiler
character(len=:), allocatable :: cxx
!> Print all commands
logical :: echo = .true.
!> Verbose output of command
Expand All @@ -96,6 +98,8 @@ module fpm_compiler
procedure :: compile_fortran
!> Compile a C object
procedure :: compile_c
!> Compile a CPP object
procedure :: compile_cpp
!> Link executable
procedure :: link
!> Check whether compiler is recognized
Expand Down Expand Up @@ -583,6 +587,41 @@ subroutine get_default_c_compiler(f_compiler, c_compiler)

end subroutine get_default_c_compiler

!> Get C++ Compiler.
subroutine get_default_cxx_compiler(f_compiler, cxx_compiler)
character(len=*), intent(in) :: f_compiler
character(len=:), allocatable, intent(out) :: cxx_compiler
integer(compiler_enum) :: id

id = get_compiler_id(f_compiler)

select case(id)

case(id_intel_classic_nix, id_intel_classic_mac, id_intel_classic_windows)
cxx_compiler = 'icpc'

case(id_intel_llvm_nix,id_intel_llvm_windows)
cxx_compiler = 'icpx'

case(id_flang, id_flang_new, id_f18)
cxx_compiler='clang'

case(id_ibmxl)
cxx_compiler='xlc++'

case(id_lfortran)
cxx_compiler = 'cc'

case(id_gcc)
cxx_compiler = 'g++'

case default
! Fall-back to using Fortran compiler
cxx_compiler = f_compiler
end select

end subroutine get_default_cxx_compiler


function get_compiler_id(compiler) result(id)
character(len=*), intent(in) :: compiler
Expand Down Expand Up @@ -754,13 +793,15 @@ end function enumerate_libraries


!> Create new compiler instance
subroutine new_compiler(self, fc, cc, echo, verbose)
subroutine new_compiler(self, fc, cc, cxx, echo, verbose)
!> New instance of the compiler
type(compiler_t), intent(out) :: self
!> Fortran compiler name or path
character(len=*), intent(in) :: fc
!> C compiler name or path
character(len=*), intent(in) :: cc
!> C++ Compiler name or path
character(len=*), intent(in) :: cxx
!> Echo compiler command
logical, intent(in) :: echo
!> Verbose mode: dump compiler output
Expand All @@ -776,6 +817,12 @@ subroutine new_compiler(self, fc, cc, echo, verbose)
else
call get_default_c_compiler(self%fc, self%cc)
end if

if (len_trim(cxx) > 0) then
self%cxx = cxx
else
call get_default_cxx_compiler(self%fc, self%cxx)
end if
end subroutine new_compiler


Expand Down Expand Up @@ -866,6 +913,24 @@ subroutine compile_c(self, input, output, args, log_file, stat)
& echo=self%echo, verbose=self%verbose, redirect=log_file, exitstat=stat)
end subroutine compile_c

!> Compile a CPP object
subroutine compile_cpp(self, input, outpu 7453 t, args, log_file, stat)
!> Instance of the compiler object
class(compiler_t), intent(in) :: self
!> Source file input
character(len=*), intent(in) :: input
!> Output file of object
character(len=*), intent(in) :: output
!> Arguments for compiler
character(len=*), intent(in) :: args
!> Compiler output log file
character(len=*), intent(in) :: log_file
!> Status flag
integer, intent(out) :: stat

call run(self%cxx // " -c " // input // " " // args // " -o " // output, &
& echo=self%echo, verbose=self%verbose, redirect=log_file, exitstat=stat)
end subroutine compile_cpp

!> Link an executable
subroutine link(self, output, args, log_file, stat)
Expand Down
Loading
0