Skip to content

macOS And Homebrew Support#54

Draft
paulhdk wants to merge 7 commits intofiliparag:masterfrom
paulhdk:macos
Draft

macOS And Homebrew Support#54
paulhdk wants to merge 7 commits intofiliparag:masterfrom
paulhdk:macos

Conversation

@paulhdk
Copy link
Copy Markdown

@paulhdk paulhdk commented Jan 13, 2026

This PR is my initial attempt at adding macOS support. Before I spend any more time on this, would you be open to merging macOS support?

Ideally, it would also like to contribute a corresponding formula to Homebrew.

GitHub provides some macOS runners, but using the existing setup with docker won't be possible for macOS, will it?

And as a side not, having to download additional sources by having to clone the project, even when it was installed through a package manager doesn't seem ideal. Is there a particular reason for this design choice? Or would you also welcome some work around building it into the app directly?

Let me know what you think, @filiparag!

@filiparag
Copy link
Copy Markdown
Owner

Hi, thanks for reaching out!

I am definitely open to extending platform support to macOS. I don't own any macOS devices, so supporting them by myself never made sense, as I wasn't able to test and dogfood. I also don't use Debian- and RHEL-based systems, but I added official binary packages, as they cover the greatest percentage of Linux users.

GitHub provides some macOS runners, but using the existing setup with docker won't be possible for macOS, will it?

Yeah, they do. I use docker for automated packaging because it makes it easier, but it is not a hard requirement. You may add macos-builder job to the existing workflow.

And as a side not, having to download additional sources by having to clone the project, even when it was installed through a package manager doesn't seem ideal. Is there a particular reason for this design choice?

I decided to go against bundling source download management inside the utility - it requires additional dependency (e.g. curl), permanent write access to the filesystem, and superuser privileges for system-wide installation. For those who only want to use wikiman for better man page search, that provides no value, only downsides.

Creating distro-specific packages for every source was also considered, but I decided against it as downloading only Makefile works reasonably well, and doesn't multiply package maintainence churn.

By the way, I just noticed some bugs when using local target on FreeBSD, so I will have to fix those. That target was already clunky, so if you have any better idea how to merge Homebrew and it together, it would be great. It would be the best if user didn't have to figure out their system-specifics at all.

@filiparag filiparag added the feature New feature or request label Jan 13, 2026
@paulhdk
Copy link
Copy Markdown
Author

paulhdk commented Jan 17, 2026

Yeah, they do. I use docker for automated packaging because it makes it easier, but it is not a hard requirement. You may add macos-builder job to the existing workflow.

Sounds good - making no promises w.r.t. timing, but I'll get on it ASAP!

And as a side not, having to download additional sources by having to clone the project, even when it was installed through a package manager doesn't seem ideal. Is there a particular reason for this design choice?

I decided to go against bundling source download management inside the utility - it requires additional dependency (e.g. curl), permanent write access to the filesystem, and superuser privileges for system-wide installation. For those who only want to use wikiman for better man page search, that provides no value, only downsides.

Creating distro-specific packages for every source was also considered, but I decided against it as downloading only Makefile works reasonably well, and doesn't multiply package maintainence churn.

Makes sense!

By the way, I just noticed some bugs when using local target on FreeBSD, so I will have to fix those. That target was already clunky, so if you have any better idea how to merge Homebrew and it together, it would be great. It would be the best if user didn't have to figure out their system-specifics at all.

Yes, the local target didn't work for me on macOS either (even though I expected it to).
I'll try figure out what the problem is with the local target.

Thank you for your quick review!

@filiparag
Copy link
Copy Markdown
Owner

filiparag commented Jan 18, 2026

Yes, the local target didn't work for me on macOS either (even though I expected it to).
I'll try figure out what the problem is with the local target.

I would like to be able to remove it completely. One way I am thinking about is to by default install in /usr/local/{bin, etc} and to have conditional check for changing it. Something along these lines:

core target example
.PHONY: core core-linux core-macos core-default

core:
	@case $(PLATFORM) in \
		"Linux")  $(MAKE) core-linux ;; \
		"Darwin") $(MAKE) core-macos ;; \
		*)        $(MAKE) core-default ;; \
	esac

core-linux:
	mkdir -p "$(BUILDDIR)/usr/bin" \
	         "$(BUILDDIR)/usr/share/$(NAME)" \
	         "$(BUILDDIR)/usr/share/licenses/$(NAME)" \
	         "$(BUILDDIR)/usr/share/man/man1"
	install -m 755 "$(WORKDIR)/$(NAME).sh" "$(BUILDDIR)/usr/bin/$(NAME)"
	cp -pr "$(WORKDIR)/sources" "$(BUILDDIR)/usr/share/$(NAME)"
	install -m 644 "$(WORKDIR)/LICENSE" "$(BUILDDIR)/usr/share/licenses/$(NAME)"
	gzip -c "$(WORKDIR)/$(NAME).1.man" > "$(BUILDDIR)/usr/share/man/man1/$(NAME).1.gz"

core-macos:
	# Commands for macOS here

core-default:
	mkdir -p "$(BUILDDIR)/usr/local/bin" \
	         "$(BUILDDIR)/usr/local/share/$(NAME)" \
	         "$(BUILDDIR)/usr/local/share/licenses/$(NAME)" \
	         "$(BUILDDIR)/usr/local/share/man/man1"
	install -m 755 "$(WORKDIR)/$(NAME).sh" "$(BUILDDIR)/usr/local/bin/$(NAME)"
	cp -pr "$(WORKDIR)/sources" "$(BUILDDIR)/usr/local/share/$(NAME)"
	install -m 644 "$(WORKDIR)/LICENSE" "$(BUILDDIR)/usr/local/share/licenses/$(NAME)"
	gzip -c "$(WORKDIR)/$(NAME).1.man" > "$(BUILDDIR)/usr/local/share/man/man1/$(NAME).1.gz"

What are your thoughts? Do you have any better idea?

@paulhdk
Copy link
Copy Markdown
Author

paulhdk commented Jan 24, 2026

What are your thoughts? Do you have any better idea?

Sounds good! The less thinking the user has to do, the better.

We would still have to account for the prefix variable though. So, before we do the platform check, we would have to check if prefix is set and then unconditionally install there, wouldn't we?

Should I open a separate PR for rewriting / removing the local target? And then we can rebase this PR once we're ready.

@filiparag
Copy link
Copy Markdown
Owner

We would still have to account for the prefix variable though. So, before we do the platform check, we would have to check if prefix is set and then unconditionally install there, wouldn't we?

Right now, the $prefix logic is install target. I think it can be moved to "build" targets, so install just blindly copies $BUILDDIR contents into the filesystem. Example:

install -m 755 "$(WORKDIR)/$(NAME).sh" "$(BUILDDIR)/$(prefix)/usr/bin/$(NAME)"

Should I open a separate PR for rewriting / removing the local target? And then we can rebase this PR once we're ready.

I will make the necessary changes in the master branch, and you can test them to make sure edge cases are covered.

@paulhdk
Copy link
Copy Markdown
Author

paulhdk commented Jan 24, 2026

Should I open a separate PR for rewriting / removing the local target? And then we can rebase this PR once we're ready.

I will make the necessary changes in the master branch, and you can test them to make sure edge cases are covered.

Sounds good!

@filiparag
Copy link
Copy Markdown
Owner

Okay, so we have a new Makefile! 🎂

I made it as consise and readable as possible, while keeping autodetection and POSIX compatibility. Now it stores installation paths as variables invoked inside targets:

SOURCES_I_PATH=	`case "$${target:-$$(uname -s)}" in \
					Linux|linux|GNU|gnu) \
						echo "$(prefix)/usr/share/doc" ;; \
					XDG|xdg|user) \
						echo "$(prefix)/$${XDG_DATA_HOME:-$(HOME)/.local/share}/doc" ;; \
					*) \
						echo "$(prefix)/usr/local/share/doc" ;; \
				esac`

Now the user doesn't have to, but can specify target variable while executing make commands to override autodetection, or do current user-only installation to $HOME.

I had to also rework how source archives are packaged (strip the absolute path), so until these changes make to a release, you will have to rebuild them locally:

cd ./build/sources/
docker compose up
# Wait for Docker workers to complete
cd ../..

# Copy to expected download path
mkdir -p srcbuild/.dl
cp ./build/sources/release/arch-wiki_*.source.tar.xz srcbuild/.dl/arch-wiki.tar.xz
cp ./build/sources/release/devdocs_*.source.tar.xz srcbuild/.dl/devdocs.tar.xz
cp ./build/sources/release/freebsd-docs_*.source.tar.xz srcbuild/.dl/freebsd-docs.tar.xz
cp ./build/sources/release/gentoo-wiki_*.source.tar.xz srcbuild/.dl/gentoo-wiki.tar.xz
cp ./build/sources/release/tldr-pages_*.source.tar.xz srcbuild/.dl/tldr-pages.tar.xz

And comment out target dependencies, so it doesn;t try to redownload them:

source-arch: #$(SOURCESDIR)/.dl/arch-wiki.tar.xz

After that it should work, but maybe some newly introduced bugs evaded my tests.

@paulhdk
Copy link
Copy Markdown
Author

paulhdk commented Feb 16, 2026

Sorry, only got around to testing this now.
Seems to be working on macOS as is! Will have to do some more testing though.

The install commands in the install target get called for every folder and subfolder in ./pkgbuild.
This leads to noisy output on macOS because the permissions of usr and usr/bin cannot be changed for instance.

What do you think about replacing them with cp or rsync?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants