Init using create-nitro-module

This commit is contained in:
2026-04-06 12:53:56 +02:00
commit b5a15a41e9
97 changed files with 6648 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
project(Omni)
cmake_minimum_required(VERSION 3.9.0)
set (PACKAGE_NAME Omni)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 20)
# Enable Raw Props parsing in react-native (for Nitro Views)
add_compile_options(-DRN_SERIALIZABLE_STATE=1)
# Define C++ library and add all sources
add_library(${PACKAGE_NAME} SHARED
src/main/cpp/cpp-adapter.cpp
)
# Add Nitrogen specs :)
include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/Omni+autolinking.cmake)
# Set up local includes
include_directories(
"src/main/cpp"
"../cpp"
)
find_library(LOG_LIB log)
# Link all libraries together
target_link_libraries(
${PACKAGE_NAME}
${LOG_LIB}
android # <-- Android core
)
+148
View File
@@ -0,0 +1,148 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:8.8.0"
}
}
def reactNativeArchitectures() {
def value = rootProject.getProperties().get("reactNativeArchitectures")
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}
def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}
apply plugin: "com.android.library"
apply plugin: 'org.jetbrains.kotlin.android'
apply from: '../nitrogen/generated/android/Omni+autolinking.gradle'
apply from: "./fix-prefab.gradle"
if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}
def getExtOrDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Omni_" + name]
}
def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Omni_" + name]).toInteger()
}
android {
namespace "com.omni"
ndkVersion getExtOrDefault("ndkVersion")
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
defaultConfig {
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
abiFilters (*reactNativeArchitectures())
buildTypes {
debug {
cppFlags "-O1 -g"
}
release {
cppFlags "-O2"
}
}
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
packagingOptions {
excludes = [
"META-INF",
"META-INF/**",
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libfolly_json.so",
"**/libfolly_runtime.so",
"**/libglog.so",
"**/libhermes.so",
"**/libhermes-executor-debug.so",
"**/libhermes_executor.so",
"**/libreactnative.so",
"**/libreactnativejni.so",
"**/libturbomodulejsijni.so",
"**/libreact_nativemodule_core.so",
"**/libjscexecutor.so"
]
}
buildFeatures {
buildConfig true
prefab true
}
buildTypes {
release {
minifyEnabled false
}
}
lintOptions {
disable "GradleCompatible"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += [
// React Codegen files
"${project.buildDir}/generated/source/codegen/java"
]
}
}
}
}
repositories {
mavenCentral()
google()
}
dependencies {
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
// Add a dependency on NitroModules
implementation project(":react-native-nitro-modules")
}
if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../src/")
libraryName = "Omni"
codegenJavaPackageName = "com.omni"
}
}
+51
View File
@@ -0,0 +1,51 @@
tasks.configureEach { task ->
// Make sure that we generate our prefab publication file only after having built the native library
// so that not a header publication file, but a full configuration publication will be generated, which
// will include the .so file
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
def matcher = task.name =~ prefabConfigurePattern
if (matcher.matches()) {
def variantName = matcher[0][1]
task.outputs.upToDateWhen { false }
task.dependsOn("externalNativeBuild${variantName}")
}
}
afterEvaluate {
def abis = reactNativeArchitectures()
rootProject.allprojects.each { proj ->
if (proj === rootProject) return
def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
config.dependencies.any { dep ->
dep.group == project.group && dep.name == project.name
}
}
if (!dependsOnThisLib && proj != project) return
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
return
}
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
// generate a libnameConfig.cmake file that will contain our native library (.so).
// See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
variants.all { variant ->
def variantName = variant.name
abis.each { abi ->
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
if (!searchDir.exists()) return
def matches = []
searchDir.eachDir { randomDir ->
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
if (prefabFile.exists()) matches << prefabFile
}
matches.each { prefabConfig ->
prefabConfig.setLastModified(System.currentTimeMillis())
}
}
}
}
}
+5
View File
@@ -0,0 +1,5 @@
Omni_kotlinVersion=2.1.20
Omni_minSdkVersion=23
Omni_targetSdkVersion=35
Omni_compileSdkVersion=34
Omni_ndkVersion=27.1.12297006
+2
View File
@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
+9
View File
@@ -0,0 +1,9 @@
#include <jni.h>
#include <fbjni/fbjni.h>
#include "OmniOnLoad.hpp"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
return facebook::jni::initialize(vm, []() {
margelo::nitro::omni::registerAllNatives();
});
}
+27
View File
@@ -0,0 +1,27 @@
package com.omni
import android.graphics.Color
import android.view.View
import androidx.annotation.Keep
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.react.uimanager.ThemedReactContext
import com.margelo.nitro.omni.HybridOmniSpec
@Keep
@DoNotStrip
class HybridOmni(val context: ThemedReactContext): HybridOmniSpec() {
// View
override val view: View = View(context)
// Props
private var _isRed = false
override var isRed: Boolean
get() = _isRed
set(value) {
_isRed = value
view.setBackgroundColor(
if (value) Color.RED
else Color.BLACK
)
}
}
+29
View File
@@ -0,0 +1,29 @@
package com.omni;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.BaseReactPackage;
import com.facebook.react.uimanager.ViewManager;
import com.margelo.nitro.omni.*;
import com.margelo.nitro.omni.views.*;
public class OmniPackage : BaseReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? = null
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider { emptyMap() }
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
val viewManagers = ArrayList<ViewManager<*, *>>()
viewManagers.add(HybridOmniManager())
return viewManagers
}
companion object {
init {
OmniOnLoad.initializeNative()
}
}
}