1

I am trying to automate the Doxygen documentation build for a MATLAB library using BitBucket pipelines. Doxygen doesn't support MATLAB natively, so I am using the m2cpp.pl filter developed by Fabrice. My Doxyfile is default apart from the following settings. FILTER_PATTERNS tells Doxygen to use the filter and PERL_PATH tells Doxygen where to find the installation of Perl needed to run the filter.

EXTENSION_MAPPING = .m=C++
FILTER_PATTERNS   = *.m=m2cpp.pl
PERL_PATH         = C:\Strawberry\perl\bin

After some daft problems with relative filepaths etc, I was able to run this on my Windows laptop with the latest version of Doxygen and it produces the expected HTML files documenting my MATLAB library.

Then I tried to repeat the same inside of a Docker Container, so that I can automate this process with BitBucket Pipelines. I have tried two Doxygen images: corentinaltepe/doxygen and hrektts/doxygen. I changed the filepaths accordingly and Doxygen runs 'fine' but produces blank documentation.

EXTENSION_MAPPING = .m=C++
FILTER_PATTERNS   = *.m=/usr/local/bin/m2cpp.pl
PERL_PATH         = /usr/bin/perl

The Doxygen readout always includes sh: 1 /usr/local/bin/m2cpp.pl: not found. I get the same message when I run the container locally or through a pipeline. Moreover, I have even run the container in interactive mode and used the shell to check that the file is present. On one occaision, I had these consecutive lines in the terminal...

root@6a1b63b93f6d:/# /usr/local/bin/doxy/m2cpp.pl
bash: /usr/local/bin/doxy/m2cpp.pl: /usr/bin/perl.exe^M: bad interpreter: No such file or directory
root@6a1b63b93f6d:/# ls -l /usr/local/bin/doxy/m2cpp.pl
-rwxrwxrwx 1 1001 1001 6892 Jan 24 15:48 /usr/local/bin/doxy/m2cpp.pl

... where Line 2 says No such file and then Line 4 confirms I have rwx permission for the very same file. I have tried several different options for putting the file in different places, accessing it via different paths etc, and its always the case that the Doxygen readout says not found.

7
  • I have just spotted the ^M carriage return character in my final code snippet. So this suggests that the m2cpp.pl filter has a Windows-style line ending in the opening line #!/usr/bin/perl.exe, which is confusing the Unix-based Docker container. Not sure how to remove this. Commented Jan 24 at 18:17
  • Opened m2cpp.pl in Vim inside of the container and it is indeed full of ^M characters so will start thinking about a fix on monday. Commented Jan 24 at 18:31
  • The ^M can be removed (when using vi) by setting the file to binary mode (:set bin) and removing the ^M characters afterwards or use the command dos2unix Commented Jan 24 at 18:32
  • Which version of doxygen are you using? (PERL_PATH has been removed in doxygen version 1.8.16, current version is 1.13.0) Furthermore the PERL_PATH didn't have anything to do with the FILTER_PATTERNS, here it is required to have the place of the perl executable in the system path or use *.m=/usr/bin/perl /usr/local/bin/m2cpp.pl Commented Jan 24 at 18:36
  • Any decent code editor will be able to save files with UNIX-style line endings. Even some simple text editors can do this. Commented Jan 24 at 19:26

1 Answer 1

1

Have now fixed this. Thanks to those who replied. I shall try my best to recount all the steps below.

Version issues

Firstly, I built my own Docker image for Doxygen. I suspect the existing images on Docker Hub (corentinaltepe/doxygen, hrektts/doxygen) would have worked too, but I wanted full visibility for debugging. Here is the Dockerfile that I used to build my Docker image. It runs Doxygen 1.9.8 because that's the latest version available in the Ubuntu default package repository at present.

FROM ubuntu:24.04

# Update
RUN apt-get update

# Install
RUN apt-get install -y vim doxygen graphviz

# Working directory
WORKDIR /doxygen/

I then generated a default Doxyfile from this version of Doxygen and changed the following settings. I think only the first two of these settings really matter, but I have included the remaining four for completeness and because they match the settings in the Doxyfile provided by Fabrice.

EXTENSION_MAPPING = .m=C++
FILTER_PATTERNS   = *.m=/doxygen/m2cpp.pl
EXTRACT_ALL       = YES
EXTRACT_PRIVATE   = YES
EXTRACT_STATIC    = YES
GENERATE_LATEX    = NO

Having made these changes, I was sure that I was using a relatively recent version of Doxygen. Moreover, I knew that my Doxyfile matched the version of Doxygen. Ie: it didn't contain deprecated settings etc. In hindsite, I don't think any of these version issues were actually causing the problem, but it was good practise to resolve them.

EOL issues

Secondly, I ran the following Git commands suggested here.

git config core.autocrlf false
git rm --cached -r .
git reset --hard

Then I opened m2cpp.pl in VSCode and changed the End of Line (EOL) Sequence in from CRLF to LF. I had tried doing this previously but suspected Git was somehow preventing the change. On this second attempt, having run those three Git commands, the change was successful. I tested this by opening m2cpp.pl from Vim inside of an Ubuntu container and using :e ++ff=unix to show ^M carriage return characters, as suggested here. Sure enough, Vim showed that there were no ^M characters.

Shebang issues

Thirdly, I changed the first line of m2cpp.pl from #!/usr/bin/perl.exe to #!/usr/bin/perl. Apparently this is another Windows vs Unix thing. That first line tells the OS where to look for the Perl interpreter and Unix doesn't like the .exe suffix.

Testing locally

Having made these changes, I built and ran my Doxygen container locally by mounting it onto the folder that contained my Dockerfile, Doxyfile, m2cpp.pl and example MATLAB code in need of documentation.

docker build doxygen-image .
docker run -it --mount type=bind,src=$pwd,dst=/doxygen/ doxygen-image

Since I ran the container in interactive mode -it, I was able to manually run commands in it. I ran the following commands inside of the /doxygen/ folder. The first one gives executable permission to m2cpp.pl and the second one runs Doxygen.

chmod +x m2cpp.pl
doxygen Doxyfile

This produced HTML files containing the expected documentation. Very good.

Testing in pipeline

Finally, I needed to run all of this automatically inside of a BitBucket Pipeline. Here is the bitbucket-pipelines.yml file that I wrote for that. There are no new 'discoveries' here - it just implements the same steps as when I was testing locally. The two export commands are needed for building Docker images inside of a BitBucket Pipeline according to this thread. The command for running docker differs slightly from when I was testing locally. I don't entirely understand the difference, but the output seems to be the same. This automatically generates HTML documentation inside of the Pipeline. At present, I then manually download these files from BitBucket, but I shall configure this to instead send them to the server that will host the documentation.

image: docker:27.4.0

pipelines:
  default:
    - step:
        name: Doxygen
        script:
          # Give executable permission to Doxygen MATLAB filter
          - chmod +x m2cpp.pl

          # Build Docker image
          - export PATH=/usr/bin:$PATH
          - export DOCKER_BUILDKIT=1
          - docker build -f Dockerfile -t doxygen-image .

          # Run Docker container, mount pwd, run Doxygen, remove container
          - docker run --rm -v $(pwd):/doxygen/ doxygen-image /bin/bash -c "doxygen Doxyfile";
        artifacts:
          - html/**
        services:
          - docker
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.