Skip to content

Conversation

@chunjin666
Copy link

Summary
This PR adds ARM64 (Apple Silicon) macOS support to wrk2 by replacing the embedded LuaJIT 2.0.3 with OpenResty
LuaJIT 2.1 as a git submodule, along with necessary platform-specific build fixes.

Motivation
The current embedded LuaJIT 2.0.3 does not support ARM64 architecture, making wrk2 unbuildable on Apple Silicon
Macs and other ARM64 platforms. With the increasing adoption of ARM64 architecture (Apple Silicon, AWS Graviton,
etc.), this limitation affects a growing number of users.

Changes
Commit 1: Replace LuaJIT 2.0.3 with OpenResty LuaJIT 2.1

  • Removed embedded LuaJIT 2.0.3 source code (no ARM64 support)
  • Added OpenResty LuaJIT 2.1 (v2.1-20241203) as git submodule
  • Fixed API compatibility: struct luaL_reg → luaL_Reg in src/script.c

Commit 2: Fix build issues on ARM64 macOS

  • Makefile - Dynamic OpenSSL detection: Use brew --prefix openssl to automatically detect OpenSSL installation
    path (supports both /opt/homebrew on Apple Silicon and /usr/local on Intel)
  • Makefile - LuaJIT bytecode linking fix: Add ld -r re-linking step to fix Mach-O "LINKEDIT segment overlap" error
    on Apple Silicon
  • src/hdr_histogram.c - Architecture detection: Add conditional compilation for x86intrin.h to only include on
    x86/x64 architectures

Why OpenResty LuaJIT instead of Official LuaJIT?

  1. ARM64 Support Status:
    - Official LuaJIT 2.0.x: No ARM64 support
    - Official LuaJIT 2.1: ARM64 support exists but branch is in perpetual beta
    - OpenResty LuaJIT 2.1: Production-grade ARM64 support
  2. Advantages:
    - Based on official LuaJIT 2.1 with full ARM64 JIT support
    - Actively maintained by OpenResty team
    - Used in production by OpenResty (nginx + LuaJIT) worldwide
    - Contains numerous ARM64-specific bug fixes
    - Fully API-compatible with official LuaJIT 2.1
  3. Migration Path: Using git submodule makes it easy to switch back to official LuaJIT once v2.1 is formally
    released.

Testing
All tests performed on macOS 15.7.3 (Sequoia) on Apple Silicon (ARM64) with OpenResty LuaJIT 2.1-20241203:

✅ Core Functionality
[x] Basic HTTP request generation
[x] Constant throughput rate control (-R parameter)
[x] HdrHistogram latency statistics (-L)
[x] Uncorrected latency statistics (-U)
[x] Multi-threaded concurrent execution

✅ Lua Script Support
[x] scripts/counter.lua - Request counting
[x] scripts/post.lua - POST requests with custom headers
[x] scripts/setup.lua - Thread initialization and data sharing
[x] scripts/report.lua - Custom report formatting with done() callback

✅ Build Verification
[x] Clean build from scratch
[x] Binary architecture: Mach-O 64-bit executable arm64
[x] All example scripts execute correctly
Sample Test Output
$ ./wrk -t2 -c10 -d5s -R100 -L http://localhost:8080/
Running 5s test @ http://localhost:8080/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.83ms 3.96ms 22.58ms 82.00%
Req/Sec nan nan 0.00 0.00%
Latency Distribution (HdrHistogram - Recorded Latency)
50.000% 3.52ms
75.000% 6.24ms
90.000% 10.18ms
99.000% 19.30ms
99.900% 22.59ms
99.990% 22.59ms
99.999% 22.59ms
100.000% 22.59ms
502 requests in 5.01s, 524.06KB read
Requests/sec: 100.28
Transfer/sec: 104.69KB

$ file wrk
wrk: Mach-O 64-bit executable arm64

Compatibility

  • ✅ ARM64 macOS: Fully tested and working
  • ⚠️ x86_64 macOS/Linux: Should work (no breaking changes to existing platforms)
  • ℹ️ Other platforms: No impact (conditional compilation used where needed)

Breaking Changes
None. All changes are additive or platform-specific.

Additional Notes

  • The .gitmodules file has been added to track the LuaJIT submodule
  • Users cloning the repository will need to run git submodule update --init --recursive
  • Build artifacts from LuaJIT are properly excluded via .gitignore

Checklist

[x] Tested on ARM64 macOS
[x] No breaking changes to existing platforms
[x] All example Lua scripts work correctly
[x] Clean build from scratch succeeds
[x] Commits are properly separated by purpose


Ready for review! Happy to address any feedback or concerns.

Changes:
- Remove embedded LuaJIT 2.0.3 (no ARM64 support)
- Add OpenResty LuaJIT 2.1 (v2.1-20241203) as git submodule
- Fix luaL_Reg type declarations in src/script.c for LuaJIT 2.1 API

LuaJIT 2.0.3 does not support ARM64 architecture. OpenResty maintains
a fork with full ARM64 support and ongoing updates.

The luaL_reg struct has been renamed to luaL_Reg (without 'struct'
keyword) in LuaJIT 2.1 API to match standard Lua conventions.
Changes:
- Makefile: Dynamically detect OpenSSL path via Homebrew
  On Apple Silicon Macs, Homebrew installs to /opt/homebrew instead of
  /usr/local. Use 'brew --prefix openssl' to detect the correct path.

- Makefile: Fix LuaJIT bytecode object file linking issue
  Add 'ld -r' re-linking step for bytecode.o to fix Mach-O linker error
  "LINKEDIT segment overlap" on Apple Silicon when linking with LuaJIT 2.1.

- src/hdr_histogram.c: Add architecture detection for x86intrin.h
  The x86intrin.h header is x86-specific. Add conditional compilation to
  only include it on x86/x64 architectures, fixing ARM64 build errors.

Tested on:
- macOS 15.2 (Sequoia) on Apple Silicon (ARM64)
- OpenResty LuaJIT 2.1-20241203
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant