diff --git a/.gitattributes b/.gitattributes index 06d51d28a9..b7e204ab21 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18,3 +18,4 @@ # file gets renamed again ... ChangeLog merge=merge-changelog +*.sh eol=lf diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4e219c3cea..eb6372c15b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,6 +38,22 @@ jobs: name: install path: _dest/ + - name: Build test programs + shell: msys2 {0} + run: | + make -C x86_64-pc-cygwin/winsup/testsuite -j8 \ + CFLAGS="-O2 -pipe -ggdb -std=gnu89 -w" check_programs + + - name: Bundle up worktree + shell: msys2 {0} + run: $WINDIR/system32/tar.exe -czf wt.tgz --exclude _dest --exclude .git --exclude wt.tgz . + + - name: Upload worktree archive + uses: actions/upload-artifact@v7 + with: + name: wt.tgz + path: wt.tgz + generate-msys2-tests-matrix: runs-on: ubuntu-latest outputs: @@ -93,3 +109,50 @@ jobs: - name: Run tests uses: msys2/msys2-tests@main + cygwin-tests: + needs: [build] + runs-on: windows-latest + steps: + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: MSYS + update: true + install: msys2-devel base-devel diffutils make perl busybox cygutils + + - name: Download worktree archive + uses: actions/download-artifact@v7 + with: + name: wt.tgz + + - name: Extract worktree + shell: msys2 {0} + run: $WINDIR/system32/tar.exe -xzf wt.tgz + + - name: Run the test suite of Cygwin + shell: msys2 {0} + run: | + export PATH=/usr/bin:$WINDIR/system32 + export MAKEFLAGS=-j8 + export MSYS=winsymlinks:nativestrict + WINSUP=$PWD/x86_64-pc-cygwin/winsup + cp $WINSUP/cygserver/cygserver.exe $WINSUP/testsuite/testinst/usr/bin/ + ( cd $WINSUP/testsuite/testinst/usr/bin && PATH=$PWD:$WINDIR/system32 "$WINDIR/System32/WindowsPowerShell/v1.0/powershell.exe" -command '& .\cygserver.exe' & ) + # cygserver is launched asynchronously; wait for it to come up before + # running the SysV IPC tests (semtest/shmtest/msgtest) that depend on + # it, otherwise they race its startup and fail intermittently. + for i in $(seq 1 60); do + "$WINDIR/System32/tasklist.exe" //FI "IMAGENAME eq cygserver.exe" 2>/dev/null | grep -qi cygserver && break + sleep 1 + done + sleep 5 + cd $WINSUP && make check AM_COLOR_TESTS=always + + - name: Upload testsuite logs + if: always() + uses: actions/upload-artifact@v7 + with: + name: cygwin-testsuite-logs + path: | + x86_64-pc-cygwin/winsup/testsuite/**/*.log + x86_64-pc-cygwin/winsup/testsuite/**/*.trs diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml deleted file mode 100644 index 998dc01576..0000000000 --- a/.github/workflows/cygwin.yml +++ /dev/null @@ -1,181 +0,0 @@ -name: cygwin - -on: workflow_dispatch - -jobs: - fedora-build: - runs-on: ubuntu-latest - container: fedora:latest - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-pc-cygwin - pkgarch: 64 - name: Fedora cross ${{ matrix.target }} - - env: - HAS_SSH_KEY: ${{ secrets.SSH_KEY != '' }} - - steps: - - uses: actions/checkout@v3 - - # install build tools - - name: Install build tools - run: | - dnf install -y autoconf automake gawk make patch perl mingw${{ matrix.pkgarch }}-gcc-c++ mingw${{ matrix.pkgarch }}-winpthreads-static mingw${{ matrix.pkgarch }}-zlib-static - - # enable 'dnf copr' - - name: Enable 'dnf copr' - run: | - dnf install -y dnf-plugins-core - - # install cross-cygwin toolchain and libs from copr - - name: Install cross-cygwin toolchain and libs and cocom from copr - run: | - dnf copr enable -y yselkowitz/cygwin - dnf install -y cygwin${{ matrix.pkgarch }}-gcc-c++ cygwin${{ matrix.pkgarch }}-gettext cygwin${{ matrix.pkgarch }}-libbfd cygwin${{ matrix.pkgarch }}-libiconv cygwin${{ matrix.pkgarch }}-zlib cocom - - # install doc tools - - name: Install doc tools - run: | - dnf install -y dblatex docbook2X docbook-xsl xmlto python3 python3-lxml python3-ply openssh-clients - fmtutil-sys --byfmt pdflatex && texhash - - # build - - name: Configure, build and install - run: | - mkdir build install - (cd winsup && ./autogen.sh) - (cd build && ../configure --target=${{ matrix.target }} --prefix=$(realpath $(pwd)/../install) ) - make -C build - make -C build/*/newlib info man - make -C build install - make -C build/*/newlib install-info install-man - - # deploy documentation - - name: Deploy documentation - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - run: | - # pushes to main are deployed as preview - # pushes to cygwin-n.n.n (but not 'cygwin-n.n.n.dev') tags are deployed as stable - # other references are ignored by this step - case "${{ github.ref }}" in - refs/heads/main) - DEST='preview' - ;; - refs/tags/cygwin-[0-9.]*) - DEST='stable' - ;; - *) - exit 0 - ;; - esac - # unfuck github fuckery of HOME in a container - unset HOME - # add the hosts public key to known_hosts - mkdir -p ~/.ssh/ - echo "cygwin.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKoejTnTCbXaIIMYfbX7t4tYUOQ2bTxZC3e/td3BageF" >> ~/.ssh/known_hosts - # load the key (restricted to scp only) into ssh-agent - ssh-agent -a $SSH_AUTH_SOCK > /dev/null - ssh-add - <<< "${{ secrets.SSH_KEY }}" - # 'make install' doesn't install faq, so instead just deploy from build directory - scp -pr build/*/winsup/doc/{cygwin-api,cygwin-ug-net,faq} cygwin-admin@cygwin.com:/sourceware/www/sourceware/htdocs/cygwin/doc/${DEST}/ - if: env.HAS_SSH_KEY == 'true' - - windows-build: - runs-on: windows-latest - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-pc-cygwin - pkgarch: x86_64 - name: Windows native ${{ matrix.pkgarch }} - - steps: - # checkout action uses the native git (we can avoid this messing up line - # endings, but this could still be dangerous e.g if we need symlinks in the - # repo) - - run: git config --global core.autocrlf input - # remove inheritable permissions since they break assumptions testsuite - # makes about file modes - - name: adjust permissions - run: | - icacls . /inheritance:r - icacls . /grant Administrators:F - - uses: actions/checkout@v3 - - # install cygwin and build tools - - name: Install Cygwin - uses: cygwin/cygwin-install-action@master - with: - platform: ${{ matrix.pkgarch }} - packages: >- - autoconf, - automake, - busybox, - cocom, - cygutils-extra, - dblatex, - dejagnu, - docbook-xml45, - docbook-xsl, - docbook2X, - gcc-g++, - gettext-devel, - libiconv, - libiconv-devel, - libzstd-devel, - make, - mingw64-${{ matrix.pkgarch }}-gcc-g++, - mingw64-${{ matrix.pkgarch }}-zlib, - patch, - perl, - python39-lxml, - python39-ply, - texlive-collection-fontsrecommended, - texlive-collection-latexrecommended, - texlive-collection-pictures, - xmlto, - zlib-devel - - # build - - name: Build Cygwin - run: >- - export PATH=/usr/bin:$(cygpath ${SYSTEMROOT})/system32 && - mkdir build install && - (cd winsup; ./autogen.sh) && - cd build && - ../configure --prefix=$(realpath $(pwd)/../install) -v && - export MAKEFLAGS=-j$(nproc) && - make && - make install && - (cd */newlib; make info man) && - (cd */newlib; make install-info install-man) - shell: C:\cygwin\bin\bash.exe --noprofile --norc -eo pipefail '{0}' - - # test - - name: Test Cygwin - run: >- - export PATH=/usr/bin:$(cygpath ${SYSTEMROOT})/system32 && - export MAKEFLAGS=-j$(nproc) && - cd build && - (export PATH=${{ matrix.target }}/winsup/testsuite/testinst/bin:${PATH} && cmd /c $(cygpath -wa ${{ matrix.target }}/winsup/cygserver/cygserver) &) && - (cd ${{ matrix.target }}/winsup; make check AM_COLOR_TESTS=always) - shell: C:\cygwin\bin\bash.exe --noprofile --norc -eo pipefail '{0}' - - # upload test logs to facilitate investigation of problems - - name: Upload test logs - uses: actions/upload-artifact@v4 - with: - name: testlogs - path: | - build/${{ matrix.target }}/winsup/testsuite/**/*.log - build/${{ matrix.target }}/winsup/testsuite/**/*.trs - if: ${{ !cancelled() }} - - # workaround problems with actions/checkout post-run step using cygwin git - - name: Avoid actions/checkout post-run step using Cygwin git - run: bash -c 'rm /usr/bin/git.exe' diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index 41190bdb7a..f30cfa5652 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -620,8 +620,8 @@ $(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\ $(newlib_build)/libm.a \ $(newlib_build)/libc.a \ -lgcc -lkernel32 -lntdll -Wl,-Map,msys.map - @$(MKDIR_P) ${target_builddir}/winsup/testsuite/testinst/bin/ - $(AM_V_at)$(INSTALL_PROGRAM) $(NEW_DLL_NAME) ${target_builddir}/winsup/testsuite/testinst/bin/$(DLL_NAME) + @$(MKDIR_P) ${target_builddir}/winsup/testsuite/testinst/usr/bin/ + $(AM_V_at)$(INSTALL_PROGRAM) $(NEW_DLL_NAME) ${target_builddir}/winsup/testsuite/testinst/usr/bin/$(DLL_NAME) # msys-2.0 import library toolopts=--cpu=@target_cpu@ --ar=@AR@ --as=@AS@ --nm=@NM@ --objcopy=@OBJCOPY@ diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am index 8f2967a6dc..915981a1be 100644 --- a/winsup/testsuite/Makefile.am +++ b/winsup/testsuite/Makefile.am @@ -318,7 +318,7 @@ check_PROGRAMS = \ # flags for linking against the just built implib # TODO: use -nostdinc and to-be-installed headers as well? LDFLAGS_FOR_TESTDLL = -nodefaultlibs -LDADD_FOR_TESTDLL = $(builddir)/../cygwin/libcygwin.a -lgcc -lkernel32 -luser32 +LDADD_FOR_TESTDLL = $(builddir)/../cygwin/libmsys-2.0.a -lgcc -lkernel32 -luser32 # flags for test executables AM_CPPFLAGS = -I$(srcdir)/libltp/include @@ -334,16 +334,24 @@ TESTS = $(check_PROGRAMS) \ # expected fail tests XFAIL_TESTS = \ + winsup.api/ltp/access01 \ + winsup.api/ltp/access05 \ + winsup.api/ltp/chmod01 \ winsup.api/ltp/setgroups01 \ winsup.api/ltp/setuid02 \ + winsup.api/ltp/stat02 \ + winsup.api/ltp/symlink01 \ + winsup.api/ltp/symlink03 \ + winsup.api/ltp/symlink05 \ winsup.api/ltp/ulimit01 \ + winsup.api/ltp/umask03 \ winsup.api/ltp/unlink08 \ winsup.api/samples/sample-fail # cygrun.sh test-runner script, and variables used by it: LOG_COMPILER = $(srcdir)/cygrun.sh -export runtime_root=$(abs_builddir)/testinst/bin +export runtime_root=$(abs_builddir)/testinst/usr/bin export cygrun=$(builddir)/mingw/cygrun # Set up things in the Cygwin 'installation' at testsuite/testinst/ to provide @@ -365,9 +373,9 @@ export cygrun=$(builddir)/mingw/cygrun check-local: $(MKDIR_P) ${builddir}/testinst/tmp - cd ${builddir}/testinst/bin && cp /usr/libexec/busybox/bin/busybox.exe sh.exe - cd ${builddir}/testinst/bin && cp /usr/libexec/busybox/bin/busybox.exe sleep.exe - cd ${builddir}/testinst/bin && cp /usr/libexec/busybox/bin/busybox.exe ls.exe + cd ${builddir}/testinst/usr/bin && cp /usr/bin/busybox.exe sh.exe + cd ${builddir}/testinst/usr/bin && cp /usr/bin/busybox.exe sleep.exe + cd ${builddir}/testinst/usr/bin && cp /usr/bin/busybox.exe ls.exe # target to build all the programs needed by check, without running check check_programs: $(check_PROGRAMS) diff --git a/winsup/testsuite/cygrun.sh b/winsup/testsuite/cygrun.sh index bf1d5cc6b5..5479543ab3 100755 --- a/winsup/testsuite/cygrun.sh +++ b/winsup/testsuite/cygrun.sh @@ -11,7 +11,7 @@ export PATH="$runtime_root:${PATH}" if [ "$1" = "./mingw/cygload" ] then windows_runtime_root=$(cygpath -m $runtime_root) - $cygrun "$exe -v -cygwin $windows_runtime_root/cygwin1.dll" + MSYS_NO_PATHCONV=1 $cygrun "$exe -v -cygwin $windows_runtime_root/msys-2.0.dll" else cygdrop $cygrun $exe fi diff --git a/winsup/testsuite/libltp/lib/search_path.c b/winsup/testsuite/libltp/lib/search_path.c index f6936094a1..3e89fe3c0c 100644 --- a/winsup/testsuite/libltp/lib/search_path.c +++ b/winsup/testsuite/libltp/lib/search_path.c @@ -139,7 +139,11 @@ printf("search_path: cmd = %s, access_mode = %d, fullpath = %d\n", cmd, access_m PATH_MAX); return -1; } - sprintf(res_path, "%s/%s", curpath, cmd); + /* Avoid a leading "//": on Cygwin/MSYS2 a path starting with + "//" denotes a UNC network path. When cwd is the root "/" + (as in the MSYS2 testsuite install-root) "%s/%s" would yield + "//cmd"; collapse curpath to "" so we emit "/cmd" instead. */ + sprintf(res_path, "%s/%s", strcmp(curpath, "/") ? curpath : "", cmd); } else strcpy(res_path, cmd); @@ -202,7 +206,8 @@ printf("search_path: tmppath = %s\n", tmppath); continue; } - sprintf(res_path, "%s/%s", tmppath, cmd); + /* Same UNC-path guard as above for the PATH-scan branch. */ + sprintf(res_path, "%s/%s", strcmp(tmppath, "/") ? tmppath : "", cmd); #if DEBUG printf("search_path: res_path = '%s'\n", res_path); #endif