Giter Club home page Giter Club logo

openorbis-ps4-toolchain's Introduction

OpenOrbis PS4 Toolchain

Release State Release Build OpenOrbis Toolchain Platforms

Note: Use the release zip or an installer, or you'll have to build the libraries and binaries yourself. It's setup this way to prevent the repo from getting bloated with binaries.

This repository contains the source code and documentation for the OpenOrbis PS4 toolchain, which enables developers to build homebrew without the need of Sony's official Software Development Kit (SDK). It contains the header files, library stubs, and tools to build applications and libraries for the PS4.

The header files as well as the library stubs may need updating to support yet undiscovered functions, so feel free to fork the repository and make pull requests to update support.

Roadmap

The following is planned to be added in future updates:

v0.6 - Debugging tools (debugger, VS integration).

v0.7 - Finalize GPU rendering support.

v1.0 - Stable release that works smoothly and has header discrepancies mostly resolved.

Documentation

Tool-specific documentation can be found alongside it's source code. The docs sub-directory also contains additional materials and documentation. Below is an overview of the purpose of each sub-directory:

Directory Contents
/bin Executables for tools for each platform (Windows in /bin/windows, Linux in /bin/linux and macOS in /bin/macos)
/docs Documentation for PS4 format specifications (reverse engineered) and the toolchain itself
/extra Extra / miscellaneous files. Currently, this includes project templates for Visual Studio
/include Contains PS4-specific + EGL/GLES and freetype headers
/lib Placeholder for built library files
/samples Example programs to get you started and for reference
/scripts Helpful scripts to view Orbis ELF (OELF) information as well as other various tools
/src Contains source code for CRT, modules, and VS templates

Setup & Installation

The clang toolchain as well as the llvm linker (lld) is needed to compile and link using this SDK. For Windows, these can be downloaded using the Pre-Built Binaries provided by LLVM. For Linux and macOS, the same page contains pre-built binaries, however you can also use the following commands (Debian/Ubuntu):

sudo apt update
sudo apt install clang
sudo apt install lld

In case you're using any Arch derivative:

sudo pacman -S clang
sudo pacman -S lld

macOS users can use Homebrew to install a pure copy of LLVM (the Apple version would not work with the toolchain!)

brew install llvm

In the future, we may include pre-built binaries for clang/lld, however for the present, it is required for you to install these separately.

The OO_PS4_TOOLCHAIN environment variable also needs to be set. On Windows, this can be done using the environment variables control panel. On linux and macOS, the following command can be added to ~/.bashrc (Debian/Ubuntu), ~/.bash_profile (macOS Mojave and lower) or ~/.zshrc (macOS Catalina):

export OO_PS4_TOOLCHAIN=[directory of installation]

If you don't wish to restart your shell, remember to source your updated profile for it to take effect.

This is needed so the build scripts and the converter tool know where to look for certain files. It is also recommended you add the root SDK directory + /bin to your path variable.

Windows Installer

For Windows, a Nullsoft scriptable installer is provided, which will automate the process of extracting the toolchain files and setting the OO_PS4_TOOLCHAIN environment variable.

Dependency .NET Core 3.0 Runtime is required to run LibOrbisPkg tools as part of build process.

Linux

For Linux, after installing the required dependencies and setting up the environment variable as noted above, you should be good to go.

macOS

For macOS, a PKG installer is provided, which will automate the process of extracting the toolchain files and setting the OO_PS4_TOOLCHAIN environment variable in both bash and zsh shells.

Creating Homebrew Projects

For Windows, /extra provides Visual Studio templates which can be added into your VS installation's templates directory to allow easy creation of homebrew projects. You can also copy and modify the solutions from the provided samples.

For Linux and macOS, /extra contains a setup-project.sh script which will create a project directory based on the hello_world sample.

Contribution

Contribution is welcome, the OpenOrbis toolchain is open source after all. For those eager to contribute, we have an actively maintained list of issues on CONTRIBUTING.md that are accessible and would be awesome to get closed. We appreciate anyone who contributes and acknowledgements will be maintained in this README.

Dependencies

There are various dependencies that need to be pulled in and compiled if you wish to build the toolchain from source. This includes musl libc, libcxx, library stubs, and other tools.

musl

https://github.com/OpenOrbis/musl

Samples all link against a statically-compiled musl libc fork for PS4.

libcxx

https://github.com/OpenOrbis/llvm-project

Samples that use C++ and use the stdlib link against a statically-compiled libcxx from an llvm-project fork for PS4.

SDL-PS4

https://github.com/OpenOrbis/SDL-PS4

The SDL2 sample uses a port of the SDL library done by znullptr.

orbis-lib-gen

https://github.com/OpenOrbis/orbis-lib-gen

The orbis-lib-gen tool is used to generate library stubs, which are needed for linking against PS4-exclusive libraries.

create-fself

https://github.com/OpenOrbis/create-fself

The create-fself tool is used to generate the final eboot.bin (for games/apps) or library PRX files that are compatible with PS4.

create-gp4

The create-gp4 tool is used to programmatically create .PKG project files for use with maxton's publishing tools.

readoelf

The readoelf tool is a custom-rolled variant of readelf for parsing Sony's modified ELF format.

LibOrbisPkg

Maxton's publishing tools are used to create param.sfo and the final .PKG file to install on the PS4.

Scripts

All scripts in the /scripts directory are Python 3 scripts, specifically targeting Python 3.7.0, with the exception of /scripts/make_fself.py. You will need Python installed on your system to run these scripts. Usage of these scripts can be found in /scripts/README.md.

autobuild.py - is an automated pkg generating script based on project dir content (may be unstable, wait for release build)

dynamic_entries.py - Gets a list of dynamic entries from the dynamic table of Orbis ELFs.

make_fself.py - Copy of flatz' script to generate fake SELF files. This functionality has now been integrated as a part of create-eboot and create-lib.

program_headers.py - Gets a list of program headers from the program header table of Orbis ELFs.

rela_entries.py - Gets a list of relocation with addend (RELA) entries from the relocation table of Orbis ELFs.

symbol_entries.py - Gets a list of symbols from the symbol table of Orbis ELFs.

License

OpenOrbis.

This project is licensed under the GPLv3 license - see the LICENSE file for details.

The accompanying LLVM binaries are licensed under the Apache 2.0 license and is owned by LLVM. Under that license, redistribution is allowed.

Credits + Special Thanks

  • Specter: Create-eboot/lib relinker, miralib, assistant suite, readelf, samples and documentation
  • CrazyVoid: Stub generator, headers, samples and documentation
  • maxton: Create-pkg pkg and SFO generation tools
  • Kiwidog: Mira, assistance, documentation
  • IDC: Lots of help with libraries and other bug fixes
  • flatz: Homebrew research and writeups, SELF reversing and documentation
  • m0rph3us1987: Help with debugging stuff
  • bigboss / psxdev: Library research and reverse engineering, used for reference by various samples
  • John Tormblom: Build system prototyping
  • LightningMods / LM: Testing via APP_HOME and lib loading help on the Mira side
  • Lord Friky: Proper macOS support
  • sleirsgoevy: Bug fixes and support, various samples
  • ChendoChap: Bug fixes and support
  • astrelsky: Bug fixes and support
  • Nikita Krapivin: C++ exception support, openGL/piglet work
  • MrSlick: Awesome logo <3
  • OpenOrbis Team
  • Other anonymous contributors

openorbis-ps4-toolchain's People

Contributors

0x199 avatar 0xcaff avatar ac2pic avatar al-azif avatar astrelsky avatar backporter avatar bucanero avatar cpasjuste avatar crazyvoidprogrammer avatar cryptogenic avatar dmiller423 avatar ethylamine avatar idc avatar illusion0001 avatar invoxiplaygames avatar john-tornblom avatar kiwidoggie avatar klairm avatar lightningmods avatar lordfriky avatar nkrapivin avatar osm-made avatar retrogamer74 avatar sleirsgoevy avatar summerfalls avatar valincius avatar xxxthedarkprogramerxxx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openorbis-ps4-toolchain's Issues

Rare obj_get_string RTLD kernel bug

Very rarely (maybe 1/30 app launches), strange behavior occurs in the PS4's rtld (runtime linker) which causes it to spam kernel log with obj_get_str: offset is out of range of string table errors.

If you let it run it's course, it leaks a bunch of memory and after a few seconds the system will panic when a kmem_alloc call fails due to kmem_map being too small.

If you exit the application before it gets to that point, you'll crash due to a bad unlink, presumably meaning even if the system doesn't run out of memory, memory corruption occurs on an important linked list.

This issue doesn't seem to be Mira-specific, but I also don't see how it could be an issue from toolchain-built ELFs because parsing bugs are deterministic. If an eboot is malformed, it should crash the loader in the same way every time. This could be an issue that's in the overlapped codebase shared among HEN implementations, including vortex's HEN and Miras.

I've opened it here for now as I'm not 100% certain it's a Mira bug / where this corruption is coming from.

<68> EXEC /app0/eboot.bin [user], vm#1, dmem#1  <290263 msec>
D/99301:Sysmodule:
libSceFios2.sprx is loaded from the development machine system.
[rtld] <68> ERROR obj_get_str:6802: offset=27 is out of range of string table of /app0/eboot.bin.
[rtld] <68> ERROR obj_get_str:6802: offset=27 is out of range of string table of /app0/eboot.biD/99301:Sysmodule:
libc.sprx is loaded from the development machine system.
n.
[rtld] <68> ERROR obj_get_str:6802: offset=27 is out of range of string table of /app0/eboot.bin.
[rtld] <68> ERROR obj_get_str:6802: offset=27 is out of range of string table of /app0/eboot.bin.
...
panic: kmem_malloc(1789526016): kmem_map too small: 37961728 total allocated
cpuid = 7

Add C++ exception support

Exceptions are also currently disabled for the libcxx build. Try to support them for v1.0 stable.

Incorrect sockaddr_in struct due to discrepancy

In linux, sockaddr_in's structure definition is:

struct sockaddr_in {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
    struct in_addr sin_addr;   /* internet address */
};

In FreeBSD, sockaddr_in's structure definition is:

struct sockaddr_in {
    uint8_t	sin_len;
    sa_family_t	sin_family;
    in_port_t	sin_port;
    struct	in_addr sin_addr;
    char	sin_zero[8];
};

This discrepancy will cause issues when calling syscalls such as bind(). This issue will need to be fixed in the output header sys/netinet/in.h from musl.

NIDs should not get written for local symbols

Currently it's possible for functions defined locally to get written to the NID table. This happens if a defined function matches the same name as one that exists in a linked in module. What lead to this discovery was MUSL having function names like inet_pton which overlap with functions found in the libkernel module.

A fix has been worked on but needs to be tested and shipped.

Library template incorrect defaults

The build script for the visual studio "OpenOrbis SPRX Project" template contains bad defaults which will lead to re-linking errors in create-lib. This is because the template tries to link against libc instead of libSceLibcInternal. This bug/regression was caused by the switch to musl and wasn't caught.

Got black screen

Tried to compile a first homebrew (hello world) and I have created the bin file with success with VS2019
But then I started the app on PS4 and I got a black screen.
Do I need Mira Hen to run it? Do I need VS2017 and not the 2019 version?
Thanks

PS4 library documentation

We should have documentation / wiki pages for known PS4 library functions and their arguments. This will be an on-going process.

Add C++ threading support

Currently threading is disabled in the libcxx build, as work needs to be done to wrap std::thread around the scePthread subsystem. This is more something that would be nice to have but probably isn't a rush, std::thread doesn't seem to be a popular component of stdlib anyway.

Incorrect pipe() syscall wrapper

The Linux signature of pipe() is int pipe(int fds[2]). However, on FreeBSD the signature is essentially int[2] pipe(void), and the file descriptors are returned in RDX:RAX.

Fully integrated VS support for projects

Currently projects are "Makefile projects" because standard VS projects do a lot of weird things internally that cause issues with using the non-MS clang. At some point it'd be nice to have full VS integration.

Link OpenOrbis Stubs to Standardized Libc

In order to have a compliant libc (with sce variable modifications sceHeapSize) newlib needs to be stabilized. Currently newlib builds for the ps4 target, but 0 of the elf-loaders aren't ghetto enough to actually load a proper ELF.

Add debugging info to output OELF

Currently debugging information like symbols is not carried over from the ELF to the Orbis ELF (OELF) intermediate file. This isn't too bad because the ELF file is still kept and can be referenced, but it would be nice to have debugging info carried over, negating the need to use the ELF file.

Library template case-sensitive warning

The library template default code includes a header:

#include "libexample.h"

However this header's name in the project is "libExample.h". In practice this doesn't break compilation but the compiler does complain and give a warning due to the incorrect case.

Potential Makefile improvements

I have made some changes (which I believe are improvements) to the hello_world Makefile. For example:

  • set the clang flag -isysroot to the SDK root,
  • use the flag -isystem for system includes,
  • use the x86_64-scei-ps4-elf target, and create orbis-ld wrapper script that appends SDK-specific linker arguments,
  • generate gp4 file and param.sfo automatically.

I posted the Makefile as a gist at: https://gist.github.com/john-tornblom/b63467bd56ea8758c99a51d7b9ccdb78
the files create-gp4 and orbis-ld needs to be placed in $OO_PS4_TOOLCHAIN/bin/linux for the Makefile to work correctly.

MiraLib Core (C#)

MiraLib is mostly done but needs to be converted to .NET core for CI.

Prerequisites for hello world sample

I have tried to build and install the hello world sample on my ps4 using the linux v0.2 SDK, but when I start the example, I get an error message complaining about corruption. I get the same behavior when installing the hello world pkg file present in the linux v0.2 SDK release zip. I'm using the HEN payload distributed by ps4gentoo, do I need some other specific payload to actually launch homebrew produced by openorbis?

Add libc/libSceFios2 dummy libraries for packages

We're going to attempt to transition Mira away from the Workaround8849 and ioctl hook for homebrew as it breaks a lot of games. Because the loader requires sce_module/libc.prx and sce_module/libSceFios2.prx and we cannot redistribute the real ones, we'll have dummy libraries that don't do anything since homebrew doesn't use these libraries anyway. Libc is static linked in, and fios2 contains exotic functions that (at least currently) aren't used. In the future, the fios2 stub can be updated to support functionality once reversed.

Tool create-eboot has slow performance on large binaries

On larger binaries (such as the SDL sample), the create-eboot tool has some serious performance issues, to the point where the SDL sample takes 15 seconds. This is extremely annoying as part of the build process.

After profiling, it seems the issue is due to unnecessary complexity in the GenerateLibrarySymbolDictionary() function

for _, symbol := range symbols {
symbolName := symbol.Name
// Skip _DYNAMIC
if symbolName == "_DYNAMIC" {
continue
}
// Check all linked libraries for the symbol
for i, libraryObj := range libraryObjs {
foundSymbol, err := checkIfLibraryContainsSymbol(libraryObj, symbolName)

pprof reports:

(pprof) list checkIfLibraryContainsSymbol
Total: 14.39s
ROUTINE ======================== main.checkIfLibraryContainsSymbol in /home/specter/openorbis/OpenOrbis-PS4-Toolchain/src/tools/create-eboot/Utils.go
      10ms     13.07s (flat, cum) 90.83% of Total
         .          .     84:
         .          .     85:// checkIfLibraryContainsSymbol takes a given library and symbol name, and checks if the library contains that symbol. It
         .          .     86:// returns a boolean of whether or not that library contains that symbol, as well as error. If we cannot get a libraries
         .          .     87:// symbol list, false and an error is returned. Otherwise, the true or false and nil are returned.
         .          .     88:func checkIfLibraryContainsSymbol(library *elf.File, symbolName string) (bool, error) {
         .     12.98s     89:	if librarySymbols, err := library.Symbols(); err == nil {
      10ms       80ms     90:		for _, sym := range librarySymbols {
         .       10ms     91:			if sym.Name == symbolName {
         .          .     92:				return true, nil
         .          .     93:			}
         .          .     94:		}
         .          .     95:	} else {
         .          .     96:		return false, err

The issue is we invoke library.Symbols() on every symbol, which adds unnecessary complexity. What should happen here is the library symbols should be cached into a map, then the symbol should be checked against said map.

Makefiles need to create intermediate directory

The makefiles for samples currently don't create the intermediate directory before building, so "no such file or directory" errors occur unless you make the dir in advance.

Meant to get to this before the toolchain dropped but it slipped through the cracks.

`create-pkg` tool is missing

create-pkg tool is described in the README.md but is missing from the repository, as well as the release tarball.

Support C++ functionality in create-eboot

C++ specific crap like .ctors, .dtors, interfaces, and other features are not currently supported in create-eboot/create-lib. We'll wanna add these to eventually fully support C++.

SDL sample

It would be nice to have an SDL library and sample as it'll help with homebrew dev.

Add C++ locking support

Currently features (even under feature level C++14), mutex, lock_guard, and other locking features are not implemented yet

std::cout fails after one write

When writing to the std::cout output stream, after one operand passes through the << operator, the badbit and failbit is set on the stream and no further operands are processed. For example, if you compile:

#include <iostream>

int main()
{
    std::cout << "Test 1 " << "Test 2" << std::endl;
    return 0;
}

Your output would look like this:

Test 1 

"Test 2" doesn't make it to stdout. I discovered ultimately the failbit gets set by the ostream's __put_character_sequence template when calling __pad_and_output().

src

template<class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>&
__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
                          const _CharT* __str, size_t __len)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif  // _LIBCPP_NO_EXCEPTIONS
        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
        if (__s)
        {
            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
            if (__pad_and_output(_Ip(__os),
                                 __str,
                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?
                                     __str + __len :
                                     __str,
                                 __str + __len,
                                 __os,
                                 __os.fill()).failed())
                __os.setstate(ios_base::badbit | ios_base::failbit); // <---- Specter: badbit and failbit are set here
        }
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch (...)
    {
        __os.__set_badbit_and_consider_rethrow();
    }
#endif  // _LIBCPP_NO_EXCEPTIONS
    return __os;
}

What's odd is ostream is used by a lot of other streams, std::stringstream and std::ofstream for instance, however these two work fine, it's only std::cout specifically that has an issue.

Currently samples use a logging class which functions similar to std::cout, but this is hacky, and fixing cout directly would be ideal if possible. Help would be greatly appreciated here as the libcxx codebase is complex and my previous attempts at root causing this have been unsuccessful.

Ability to generate/link stubs by nid only

Currently there is no way to call functions that we have nids for but no names for. There is a fix/workaround for this, but currently isn't supported. Eventually add support for this.

Fix text rendering in _common/graphics.cpp

Current text rendering is rough around the edges because of the draw function erroneously not factoring in the greyscale bitmap to blend with the background. The SDL sample has a fixed text rendering function but it needs to be brought over to the common one for other samples as well.

Put libraries on CI

We should probably put libraries on Continuous Integration (CI) that way any updates can be pulled immediately from the artifacts without having to wait for them to be bundled in a release.

AF_INET6 is 28 on PS4

AF_INET6 is 28 on both stock FreeBSD and PS4, but is erroneously set to 10 in the OpenOrbis headers. There may be other similar errors.

"Debug" builds of samples do not have debug symbols

Although the build directory is named as "Debug", the Makefile does not specify the -g compiler flag, which results in the binaries being built without debug_info.

A fix is to add -g to CFLAGS and LFLAGS inside each Makefile.

CMath C++ header broken

using ::signbit;
using ::fpclassify;
using ::isfinite;
using ::isinf;
using ::isnan;
using ::isnormal;
using ::isgreater;
using ::isgreaterequal;
using ::isless;
using ::islessequal;
using ::islessgreater;
using ::isunordered;
using ::isunordered;

These functions are not implemented and making flatbuffers fail.

MiraLib Bindings

We'd like bindings provided for MiraLib to use in C, C++, Python, and Rust. The python binding is being tackled by myself, however help is welcome for the other bindings once the MiraLib Core (#15) goes up.

  • C
  • C++
  • Python
  • Rust

Include PkgTool.Core in Linux distribution

Please consider including PkgTool.Core with the linux SDK. This enables full automation of making pkg files on linux using the following makefile target:

TITLE      := My Homebrew
VERSION    := 1.00
TITLE_ID   := BREW00001
CONTENT_ID := IV0000-BREW00001_00-MYHOMEBREW000000

sce_sys/param.sfo:
	PkgTool.Core sfo_new $@
	PkgTool.Core sfo_setentry $@ APP_TYPE --type Integer --maxsize 4 --value 1 
	PkgTool.Core sfo_setentry $@ APP_VER --type Utf8 --maxsize 8 --value '$(VERSION)'
	PkgTool.Core sfo_setentry $@ ATTRIBUTE --type Integer --maxsize 4 --value 0  
	PkgTool.Core sfo_setentry $@ CATEGORY --type Utf8 --maxsize 4 --value 'gd'  
	PkgTool.Core sfo_setentry $@ CONTENT_ID --type Utf8 --maxsize 48 --value '$(CONTENT_ID)'
	PkgTool.Core sfo_setentry $@ DOWNLOAD_DATA_SIZE --type Integer --maxsize 4 --value 0 
	PkgTool.Core sfo_setentry $@ SYSTEM_VER --type Integer --maxsize 4 --value 0  
	PkgTool.Core sfo_setentry $@ TITLE --type Utf8 --maxsize 128 --value '$(TITLE)'
	PkgTool.Core sfo_setentry $@ TITLE_ID --type Utf8 --maxsize 12 --value '$(TITLE_ID)'
	PkgTool.Core sfo_setentry $@ VERSION --type Utf8 --maxsize 8 --value '$(VERSION)'

Bleeding-edge binaries are published at
https://ci.appveyor.com/project/maxton/liborbispkg/build/artifacts

Fix CRLF line-endings on linux scripts

The setup-project.sh and setup-toolchain.sh scripts in /extra use CRLF line endings instead of LF endings, which causes errors when running the scripts.

Implicitly disable buffering on stdout (musl)

Buffering should just be disabled on stdout due to buffering not being handled well. All the samples disable buffering via setvbuf, but we may as well make it so you don't have to do this to get all the data sent to stdout.

Rework various samples

Some samples only really do useful stuff through the kernel log, which doesn't make it super obvious what's actually happening. There are also some graphic-related samples that could use some adjustments.

With C++ support, also rework some samples to utilize C++.

  • Font sample rewrite
  • Graphics sample rewrite
  • Hello world sample rewrite
  • Input sample rewrite
  • PNG decoding sample rewrite
  • System sample rewrite
  • Threading sample rewrite

Script release creation + create new windows installer

Currently creating releases is a pain and involves some manual work. Simplify this by creating a script to do it. We'll also move away from NSIS as the installer is lacking in features.

  • Release script
  • New installer

GNM Command Driver

As per study, We need to write a driver for gnm commands if we want to be able to fully use gnm for 3d graphics.

Bigboss(psxdev) has made some progress on this and when this toolchain is public, i'll assign him to this issue.

  • CrazyVoid

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.