Skip to content

Commit

Permalink
Merge pull request #2 from msaelices/main
Browse files Browse the repository at this point in the history
Fixes in variadic arguments. Include some new logic from mojo-stdlib-extensions. Adapted to latest Mojo nightly. Unit tests
  • Loading branch information
crisadamo authored Nov 17, 2024
2 parents c876e4c + 8270c5e commit bb8afe8
Show file tree
Hide file tree
Showing 22 changed files with 7,346 additions and 2,063 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# GitHub syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
20 changes: 20 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Main workflow

on:
push:
branches: [main]

permissions:
contents: write

jobs:
test:
uses: ./.github/workflows/test.yml

package:
uses: ./.github/workflows/package.yml

publish:
uses: ./.github/workflows/publish.yml
secrets:
PREFIX_API_KEY: ${{ secrets.PREFIX_API_KEY }}
23 changes: 23 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Create package

on:
workflow_call:

jobs:
package:
name: Package
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run the package command
run: |
curl -ssL https://magic.modular.com | bash
source $HOME/.bash_profile
magic run mojo package src/libc -o libc.mojopkg
- name: Upload package as artifact
uses: actions/upload-artifact@v4
with:
name: libc-package
path: libc.mojopkg
44 changes: 44 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Build and publish

on:
workflow_call:
secrets:
PREFIX_API_KEY:
required: true

jobs:
publish:
name: Publish package
strategy:
matrix:
include:
- { target: linux-64, os: ubuntu-latest }
- { target: osx-arm64, os: macos-14 }
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 5
defaults:
run:
shell: bash
steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Build package for target platform
env:
TARGET_PLATFORM: ${{ matrix.target }}
PREFIX_API_KEY: ${{ secrets.PREFIX_API_KEY }}
CONDA_BLD_PATH: ${{ runner.workspace }}/.rattler
run: |
curl -ssL https://magic.modular.com | bash
source $HOME/.bash_profile
# Temporary method to fetch the rattler binary.
RATTLER_BINARY="rattler-build-aarch64-apple-darwin"
if [[ $TARGET_PLATFORM == "linux-64" ]]; then RATTLER_BINARY="rattler-build-x86_64-unknown-linux-musl"; fi
curl -SL --progress-bar https://github.com/prefix-dev/rattler-build/releases/latest/download/${RATTLER_BINARY} -o rattler-build
chmod +x rattler-build
# Build and push
magic run build --target-platform=$TARGET_PLATFORM
magic run publish -c mojo-community-nightly
17 changes: 17 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Run the testing suite

on:
workflow_call:

jobs:
test:
name: Run tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run the test suite
run: |
curl -ssL https://magic.modular.com | bash
source $HOME/.bash_profile
magic run mojo test -I src/ tests/
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# pixi environments
.pixi
*.egg-info
# magic environments
.magic
output
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: local
hooks:
- id: mojo-format
name: mojo-format
entry: magic run mojo format -l 88
language: system
files: '\.(mojo|🔥)$'
stages: [commit]
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TO FIGURE IT OUT
49 changes: 39 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,50 @@
# Mojo's libc support

> Note: its a work in progress. Variadic syscall not working at the moment.
## Getting Started

The only dependency for `libc` is Mojo.

You can install Mojo following the instructions from the [Modular website](https://www.modular.com/max/mojo).

Once you have created a Mojo project using the `magic` tool,

1. Add the `mojo-community` channel to your `mojoproject.toml`, e.g:
```toml
[project]
channels = ["conda-forge", "https://conda.modular.com/max", "https://repo.prefix.dev/mojo-community"]
```
2. Add `libc` as a dependency:
```toml
[dependencies]
libc = ">=0.1.4"
```
3. Run `magic install` at the root of your project, where `mojoproject.toml` is located
4. `libc` should now be installed as a dependency. You can import libc functions from the library, e.g:
```mojo
from libc import socket
```
## Supported Functionality
### Basic socket connections
Example for [server](https://github.com/crisadamo/mojo-libc/blob/main/Libc.mojo#L1575) and [client](https://github.com/crisadamo/mojo-libc/blob/main/Libc.mojo#L1534)
> Note: `getaddrinfo` is not working properly.
See the examples in [examples/sockets/](examples/sockets/) directory.
To test the socket functionality there are two functions:
- `__test_socket_server__` that start listening for connections on 127.0.0.1:8083 and once a client connects it send the `"Hello, Mojo!"` message.
- `__test_socket_client__` that connects to 127.0.0.1:8083 send the message `"Hello, world Server"` and prints the reply from the server.
### Basic file system operations
In order to test it you need to create two notebooks, on the first one you need to run the `__test_socket_server__()` and then on the second one run `__test_socket_client__()`.
See the examples in [examples/files/](examples/files/) directory.
## Building the project
To build the project, execute the following command:
### Basic file system operations
Example [here](https://github.com/crisadamo/mojo-libc/blob/main/Libc.mojo#L1636)
```bash
./scripts/build.sh
```

## Running the tests

To run the tests, execute the following command:

To test it you can play around with the `__test_file__` function.
```bash
./scripts/run-tests.sh
```
20 changes: 20 additions & 0 deletions examples/files/print.mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from libc import (
FD_STDOUT,
c_char,
c_int,
c_void,
printf,
strlen,
write,
)


fn main():
var format_str = String("Hello %s\n")
var format_ptr = format_str.unsafe_cstr_ptr()
var name = String("world")
var name_ptr = name.unsafe_cstr_ptr()
_ = printf(format_ptr, name_ptr)
var msg = String("Hello world, again\n")
var msg_ptr = msg.unsafe_cstr_ptr()
_ = write(FD_STDOUT, msg_ptr.bitcast[c_void](), len(msg))
69 changes: 69 additions & 0 deletions examples/sockets/client.mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from memory import UnsafePointer
from utils import StaticTuple

from libc import (
AF_INET,
AI_PASSIVE,
SOCK_STREAM,
SHUT_RDWR,
addrinfo,
c_char,
connect,
getaddrinfo,
htons,
in_addr,
sizeof,
sockaddr,
sockaddr_in,
socket,
shutdown,
)


fn get_ip_address(host: String) raises -> in_addr:
var host_ptr = host.unsafe_cstr_ptr()
var my_addrinfo = addrinfo()
var servinfo = UnsafePointer[addrinfo]().alloc(1)
servinfo.init_pointee_move(my_addrinfo)

var hints = addrinfo()
hints.ai_family = AF_INET
hints.ai_socktype = SOCK_STREAM
hints.ai_flags = AI_PASSIVE

var error = getaddrinfo(
host_ptr,
UnsafePointer[c_char](),
UnsafePointer.address_of(hints),
UnsafePointer.address_of(servinfo),
)
if error != 0:
raise Error("getaddrinfo failed: {}".format(error))

var addrinfo = servinfo[]
var ai_addr = addrinfo.ai_addr

return ai_addr.bitcast[sockaddr_in]()[].sin_addr


fn main() raises:
var ip: in_addr
var host = "localhost"
var port = 8080
print("Connecting to ", host, " on port ", port)

ip = get_ip_address(host)

# Convert ip address to network byte order.
var addr: sockaddr_in = sockaddr_in(
AF_INET, htons(port), ip, StaticTuple[c_char, 8](0, 0, 0, 0, 0, 0, 0, 0)
)
var addr_ptr = UnsafePointer[sockaddr_in].address_of(addr).bitcast[sockaddr]()
var sock = socket(AF_INET, SOCK_STREAM, 0)

if connect(sock, addr_ptr, sizeof[sockaddr_in]()) == -1:
print("Failed to connect to server")
else:
print("Connected to server")

_ = shutdown(sock, SHUT_RDWR)
Empty file added examples/sockets/server.mojo
Empty file.
Loading

0 comments on commit bb8afe8

Please sign in to comment.