diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c21641d..75bff94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,50 +7,6 @@ on: - '*' pull_request: jobs: - ubuntu: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - perl-version: ['5.10', '5.14', '5.20', '5.28', '5.32'] - include: - - perl-version: '5.30' - os: ubuntu-latest - release-test: true - coverage: true - container: perl:${{ matrix.perl-version }} - steps: - - uses: actions/checkout@v2 - - uses: perl-actions/install-with-cpanm@v1 - with: - args: -n --installdeps --with-recommends . - sudo: false - - run: perl -V - - name: Build - run: | - perl Makefile.PL - make - - name: Run release tests # before others as may install useful stuff - if: ${{ matrix.release-test }} - env: - RELEASE_TESTING: 1 - run: | - apt-get update && apt-get install -y libfile-copy-recursive-perl - cpanm -n --installdeps --with-develop . - prove -brj4 xt - - name: Run tests (no coverage) - if: ${{ !matrix.coverage }} - run: prove -brj4 t - - name: Run tests (with coverage) - if: ${{ matrix.coverage }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TESTING: 1 - run: | - cpanm -n Devel::Cover::Report::Coveralls - HARNESS_PERL_SWITCHES='-MDevel::Cover=-delete,-ignore,Alien/OpenMP/Install/Files\\.pm$' prove -brj4 t xt - cover -report Coveralls non-linux: runs-on: ${{ matrix.os }} strategy: @@ -69,7 +25,7 @@ jobs: - name: Run tests run: | perl Makefile.PL - make + gmake prove -brj4 t darwin: runs-on: macOS-latest diff --git a/.github/workflows/test-gccs.yml b/.github/workflows/test-gccs.yml new file mode 100644 index 0000000..6dd329f --- /dev/null +++ b/.github/workflows/test-gccs.yml @@ -0,0 +1,75 @@ +name: Perl CI with Inline::C and OpenMP + +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false # Ensure all jobs run even if one fails + matrix: + os: ["ubuntu-latest"] + perl: ["5.40.1", "5.38.3", "5.36.3", "5.34.3", "5.32.1", "5.30.3", "5.28.3", "5.26.3", "5.24.4", "5.22.3", "5.20.0", "5.18.4", "5.16.3", "5.14.4", "5.12.5"] + gcc: ["13", "11", "9"] # Different GCC versions to test + + name: Perl ${{ matrix.perl }} with GCC-${{ matrix.gcc }} on ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + # Install the requested GCC version and dependencies + - name: Install GCC-${{ matrix.gcc }} and Dependencies + run: | + sudo apt update + sudo apt install -y gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }} build-essential libgomp1 curl + + # Switch GCC at the OS level using update-alternatives + - name: Set GCC-${{ matrix.gcc }} as Default + run: | + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ matrix.gcc }} 100 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${{ matrix.gcc }} 100 + sudo update-alternatives --set gcc /usr/bin/gcc-${{ matrix.gcc }} + sudo update-alternatives --set g++ /usr/bin/g++-${{ matrix.gcc }} + + export CC=/usr/bin/gcc + export CXX=/usr/bin/g++ + echo "CC=$CC" >> $GITHUB_ENV + echo "CXX=$CXX" >> $GITHUB_ENV + + echo "Using system GCC version:" + gcc --version + + # Install Perlbrew + - name: Install Perlbrew + run: | + curl -L https://install.perlbrew.pl | bash + echo 'export PERLBREW_ROOT=$HOME/perl5/perlbrew' >> $HOME/.bashrc + echo 'source $HOME/perl5/perlbrew/etc/bashrc' >> $HOME/.bashrc + export PERLBREW_ROOT=$HOME/perl5/perlbrew + export PATH="$PERLBREW_ROOT/bin:$PATH" + source $HOME/perl5/perlbrew/etc/bashrc + perlbrew available + + # Install and Use the Requested Perl Version + - name: Install Perl ${{ matrix.perl }} with GCC-${{ matrix.gcc }} + run: | + export PERLBREW_ROOT=$HOME/perl5/perlbrew + export PATH="$PERLBREW_ROOT/bin:$PATH" + source $HOME/perl5/perlbrew/etc/bashrc + + perlbrew --verbose --notest install perl-${{ matrix.perl }} -Dcc=$CC + perlbrew use perl-${{ matrix.perl }} + perlbrew install-cpanm + + perl -V + perl -v + + # Install Required Perl Modules + - name: Install Required Perl Modules + run: | + export PERLBREW_ROOT=$HOME/perl5/perlbrew + export PATH="$PERLBREW_ROOT/bin:$PATH" + source $HOME/perl5/perlbrew/etc/bashrc + perlbrew use perl-${{ matrix.perl }} + cpanm --verbose --notest Inline::C + cpanm --verbose . diff --git a/Changes b/Changes index 573274f..0907df8 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ -{{$NEXT}} -- doc tweaks +0.003007 2022-05-14 20:04:34+01:00 Europe/London +- Fixing build that breaks when CNAME is a path to + gcc and not just "gcc" 0.003006 2021-11-01 21:46:06+01:00 Europe/London - Updated Inline::C integration via Alien::OpenMP::Inline diff --git a/dist.ini b/dist.ini index 58c0ab8..a3e711f 100644 --- a/dist.ini +++ b/dist.ini @@ -2,10 +2,10 @@ name = Alien-OpenMP license = Perl_5 author = oodler copyright_holder = oodler -copyright_year = 2021 +copyright_year = 2021-present +[VersionFromModule] [@Starter::Git] revision = 5 -managed_versions = 1 regenerate = Makefile.PL regenerate = META.json [AlienBuild] diff --git a/lib/Alien/OpenMP/configure.pm b/lib/Alien/OpenMP/configure.pm index bf898bb..8e13559 100644 --- a/lib/Alien/OpenMP/configure.pm +++ b/lib/Alien/OpenMP/configure.pm @@ -3,7 +3,8 @@ use strict; use warnings; use Config; -our $CCNAME = $ENV{CC} || $Config::Config{ccname}; +# ExtUtils::CBuilder uses cc not ccname +our $CCNAME = $ENV{CC} || $Config::Config{cc}; our $OS = $^O; my $checked = 0; @@ -84,8 +85,20 @@ sub version_from_preprocessor { sub _openmp_defined { my $define = pop; + # From https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md - my $versions = {200505 => '2.5', 200805 => '3.0', 201107 => '3.1', 201307 => '4.0', 201511 => '4.5', 201811 => '5.0'}; + # also https://www.openmp.org/specifications/ + my $versions = { + 200505 => '2.5', + 200805 => '3.0', + 201107 => '3.1', + 201307 => '4.0', + 201511 => '4.5', + 201811 => '5.0', + 202011 => '5.1', + 202111 => '5.2', + 202411 => '6.0', + }; return $versions->{$define || ''} || 'unknown'; } @@ -94,12 +107,30 @@ sub _reset { $checked = 0; } sub _update_supported { return if $checked; + require File::Basename; + + # handles situation where $CCNAME is gcc as part of a path + $CCNAME = File::Basename::basename($CCNAME); + if ($OS eq 'darwin') { require File::Which; require Path::Tiny; # The issue here is that ccname=gcc and cc=cc as an interface to clang - $supported->{darwin} = {cflags => ['-Xclang', '-fopenmp'], libs => ['-lomp'],}; + # First check if clang/gcc, then discern omp location + my $flavour = _compiler_flavour(); + if ($flavour eq 'clang' || $flavour eq 'default') { + $supported->{darwin} = {cflags => ['-Xclang', '-fopenmp'], libs => ['-lomp'],}; + $supported->{$CCNAME} ||= {auto_include => join qq{\n}, ('#include ')}; + } + elsif ($flavour eq 'gcc') { + $supported->{darwin} = {cflags => ['-fopenmp'], libs => ['-lomp'],}; + $supported->{$CCNAME} ||= {auto_include => join qq{\n}, ('#include ')}; + } + else { + return ++$checked; + } + if (my $mp = File::Which::which('port')) { # macports /opt/local/bin/port @@ -108,14 +139,22 @@ sub _update_supported { unshift @{$supported->{darwin}{libs}}, "-L$mp_prefix/lib/libomp"; } else { - # homebrew has the headers and library in /usr/local - push @{$supported->{darwin}{cflags}}, "-I/usr/local/include"; - unshift @{$supported->{darwin}{libs}}, "-L/usr/local/lib"; + # homebrew has the headers and library in /usr/local, but is not always symlinked + push @{$supported->{darwin}{cflags}}, "-I/usr/local/include", "-I/opt/homebrew/opt/libomp/include"; + unshift @{$supported->{darwin}{libs}}, "-L/usr/local/lib", "-L/opt/homebrew/opt/libomp/lib"; } } $checked++; } +# not looking for openmp +sub _compiler_flavour { + my $defines = qx{$CCNAME -dM -E - < /dev/null}; + return 'clang' if ($defines =~ m{^#define __clang__}m); + return 'gcc' if ($defines =~ m{^#define __GCC_}m && $defines =~ m{^#define __APPLE__}m); + return 'default'; +} + 1; =encoding utf8 diff --git a/t/03-configure.t b/t/03-configure.t index f894da4..bb2b7d8 100644 --- a/t/03-configure.t +++ b/t/03-configure.t @@ -25,6 +25,8 @@ subtest 'gcc' => sub { }; subtest 'darwin clang/gcc homebrew' => sub { + plan skip_all => 'Mocking does not work on MSWin32' + if $^O eq 'MSWin32'; local $Alien::OpenMP::configure::CCNAME = 'gcc'; local $Alien::OpenMP::configure::OS = 'darwin'; local $ENV{PATH} = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"; @@ -86,6 +88,16 @@ subtest 'darwin, missing dependencies' => sub { like $stderr, qr{Support can be enabled by using Homebrew or Macports}, 'unsupported compiler name'; }; +subtest '/full/path/to/gcc' => sub { + local $Alien::OpenMP::configure::CCNAME = '/full/path/to/gcc'; + local $Alien::OpenMP::configure::OS = 'linux'; + my $omp_flag = q{-fopenmp}; + Alien::OpenMP::configure->_reset; + is +Alien::OpenMP::configure->is_known, 1, q{known}; + is +Alien::OpenMP::configure->cflags, $omp_flag, q{Found expected OpenMP compiler switch for gcc.}; + is +Alien::OpenMP::configure->lddlflags, $omp_flag, q{Found expected OpenMP linker switch for gcc.}; +}; + subtest 'preprocessor parsing' => sub { my $result = Alien::OpenMP::configure->version_from_preprocessor(<<'END_OF_CPP'); #define _LP64 1