Skip to content

Commit 07fce81

Browse files
committed
Added possiblity to start with C++ code in library
1 parent 0621657 commit 07fce81

File tree

14 files changed

+1104
-1109
lines changed

14 files changed

+1104
-1109
lines changed

src/create.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import pack from '../package.json';
1212

1313
const TEMPLATE = path.resolve(__dirname, '../templates/library');
1414
const BINARIES = /(gradlew|\.(jar|keystore|png|jpg|gif))$/;
15+
const CPP_FILES = path.resolve(__dirname, '../templates/cppLibrary');
1516

1617
export default async function create(argv: yargs.Arguments<any>) {
1718
const folder = path.join(process.cwd(), argv.name);
@@ -51,6 +52,7 @@ export default async function create(argv: yargs.Arguments<any>) {
5152
authorEmail,
5253
authorUrl,
5354
githubUrl: repo,
55+
useCpp,
5456
} = (await inquirer.prompt([
5557
{
5658
type: 'input',
@@ -118,13 +120,20 @@ export default async function create(argv: yargs.Arguments<any>) {
118120
},
119121
validate: input => /^https?:\/\//.test(input) || 'Must be a valid URL',
120122
},
123+
{
124+
type: 'confirm',
125+
name: 'useCpp',
126+
message: 'Does your library use C++ code?',
127+
default: false,
128+
},
121129
])) as {
122130
slug: string;
123131
description: string;
124132
authorName: string;
125133
authorEmail: string;
126134
authorUrl: string;
127135
githubUrl: string;
136+
useCpp: boolean;
128137
};
129138

130139
const project = slug.replace(/^(react-native-|@[^/]+\/)/, '');
@@ -143,6 +152,7 @@ export default async function create(argv: yargs.Arguments<any>) {
143152
.slice(1)}`,
144153
package: slug.replace(/[^a-z0-9]/g, '').toLowerCase(),
145154
podspec: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''),
155+
useCpp,
146156
},
147157
author: {
148158
name: authorName,
@@ -176,6 +186,9 @@ export default async function create(argv: yargs.Arguments<any>) {
176186
};
177187

178188
await copyDir(TEMPLATE, folder);
189+
if (options.project.useCpp) {
190+
await copyDir(CPP_FILES, folder);
191+
}
179192

180193
try {
181194
await spawn.sync(
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
cmake_minimum_required(VERSION 3.4.1)
2+
3+
set (CMAKE_VERBOSE_MAKEFILE ON)
4+
set (CMAKE_CXX_STANDARD 11)
5+
6+
add_library(cpp
7+
SHARED
8+
../cpp/example.cpp
9+
cpp-adapter.cpp
10+
)
11+
12+
# Specifies a path to native header files.
13+
include_directories(
14+
../cpp
15+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <jni.h>
2+
#include "example.h"
3+
4+
extern "C"
5+
JNIEXPORT jint JNICALL
6+
Java_com_<%= project.package %>_<%= project.name %>_nativeMultiply(JNIEnv *env, jclass type, jint a, jint b) {
7+
return example::multiply(a, b);
8+
}

templates/cppLibrary/cpp/example.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "example.h"
2+
3+
namespace example {
4+
int multiply(int a, int b) {
5+
return a * b;
6+
}
7+
}

templates/cppLibrary/cpp/example.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef EXAMPLE_H
2+
#define EXAMPLE_H
3+
4+
namespace example {
5+
int multiply(int a, int b);
6+
}
7+
8+
#endif /* EXAMPLE_H */

templates/library/<%= project.podspec %>.podspec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ Pod::Spec.new do |s|
1313
s.platforms = { :ios => "9.0" }
1414
s.source = { :git => "<%= repo %>.git", :tag => "#{s.version}" }
1515

16-
s.source_files = "ios/**/*.{h,m}"
16+
s.source_files = "ios/**/*.{h,m,mm}"
1717

18+
<% if(project.useCpp==true){ %>
19+
s.source_files = "ios/**/*.{h,m,mm}", "cpp/**/*.{h,cpp}"
20+
<% } else{ %>
21+
s.source_files = "ios/**/*.{h,m,mm}"
22+
<% } %>
1823
s.dependency "React"
1924
end

templates/library/android/build.gradle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,22 @@ android {
3333
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
3434
versionCode 1
3535
versionName "1.0"
36+
<%if (project.useCpp==true) {%>
37+
externalNativeBuild {
38+
cmake {
39+
cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
40+
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
41+
}
42+
}
43+
<%}%>
44+
}
45+
<%if (project.useCpp==true) {%>
46+
externalNativeBuild {
47+
cmake {
48+
path "CMakeLists.txt"
49+
}
3650
}
51+
<%}%>
3752
buildTypes {
3853
release {
3954
minifyEnabled false

templates/library/android/src/main/java/com/<%= project.package %>/<%= project.name %>Module.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,23 @@ class <%= project.name %>Module(reactContext: ReactApplicationContext) : ReactCo
1717
fun getDeviceName(promise: Promise) {
1818
promise.resolve(android.os.Build.MODEL)
1919
}
20+
<%if (project.useCpp==true) {%>
21+
22+
@ReactMethod
23+
fun multiply(a: Int, b: Int, promise: Promise) {
24+
promise.resolve(nativeMultiply(a, b));
25+
}
26+
27+
external fun nativeMultiply(a: Int, b: Int): Int;
28+
29+
companion object
30+
{
31+
32+
// Used to load the 'native-lib' library on application startup.
33+
init
34+
{
35+
System.loadLibrary("cpp")
36+
}
37+
}
38+
<%}%>
2039
}

templates/library/example/src/App.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,24 @@ import <%= project.name %> from '<%= project.slug %>';
44

55
export default function App() {
66
const [deviceName, setDeviceName] = React.useState('');
7+
<%if (project.useCpp==true) {%>
8+
const [value, setValue] = React.useState();
9+
<%}%>
10+
711

812
React.useEffect(() => {
913
<%= project.name %>.getDeviceName().then(setDeviceName);
14+
<%if (project.useCpp==true) {%>
15+
<%= project.name %>.multiply(2, 3).then(setValue);
16+
<%}%>
1017
}, []);
1118

1219
return (
1320
<View style={styles.container}>
1421
<Text>Device name: {deviceName}</Text>
22+
<%if (project.useCpp==true) {%>
23+
<Text>C++ mulitply value: {value}</Text>
24+
<%}%>
1525
</View>
1626
);
1727
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#import <React/RCTBridgeModule.h>
22

3+
<%if (project.useCpp==true) {%>
4+
#ifdef __cplusplus
5+
6+
#import "example.h"
7+
8+
#endif
9+
<%}%>
10+
311
@interface <%= project.name %> : NSObject <RCTBridgeModule>
412

513
@end

templates/library/ios/<%= project.name %>.m renamed to templates/library/ios/<%= project.name %>.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ @implementation <%= project.name %>
1515
resolve(deviceInfo.name);
1616
}
1717

18+
<%if (project.useCpp==true) {%>
19+
RCT_EXPORT_METHOD(multiply:(nonnull NSNumber*)a withB:(nonnull NSNumber*)b resolver:(RCTPromiseResolveBlock)resolve
20+
withReject:(RCTPromiseRejectBlock)reject)
21+
{
22+
long result = example::multiply([a longValue], [b longValue]);
23+
24+
resolve(@(result));
25+
}
26+
<%}%>
27+
1828
@end

templates/library/ios/<%= project.name %>.xcodeproj/project.pbxproj

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10-
B3E7B58A1CC2AC0600A0062D /* <%= project.name %>.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* <%= project.name %>.m */; };
10+
5E46D8CD2428F78900513E24 /* example.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E46D8CB2428F78900513E24 /* example.cpp */; };
11+
5E555C0D2413F4C50049A1A2 /* <%= project.name %>.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* <%= project.name %>.mm */; };
1112
/* End PBXBuildFile section */
1213

1314
/* Begin PBXCopyFilesBuildPhase section */
@@ -24,8 +25,10 @@
2425

2526
/* Begin PBXFileReference section */
2627
134814201AA4EA6300B7C361 /* lib<%= project.name %>.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = lib<%= project.name %>.a; sourceTree = BUILT_PRODUCTS_DIR; };
28+
5E46D8CB2428F78900513E24 /* example.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = example.cpp; path = ../cpp/example.cpp; sourceTree = "<group>"; };
29+
5E46D8CC2428F78900513E24 /* example.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = example.h; path = ../cpp/example.h; sourceTree = "<group>"; };
2730
B3E7B5881CC2AC0600A0062D /* <%= project.name %>.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = <%= project.name %>.h; sourceTree = "<group>"; };
28-
B3E7B5891CC2AC0600A0062D /* <%= project.name %>.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = <%= project.name %>.m; sourceTree = "<group>"; };
31+
B3E7B5891CC2AC0600A0062D /* <%= project.name %>.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = <%= project.name %>.mm; sourceTree = "<group>"; };
2932
/* End PBXFileReference section */
3033

3134
/* Begin PBXFrameworksBuildPhase section */
@@ -50,8 +53,10 @@
5053
58B511D21A9E6C8500147676 = {
5154
isa = PBXGroup;
5255
children = (
56+
5E46D8CB2428F78900513E24 /* example.cpp */,
57+
5E46D8CC2428F78900513E24 /* example.h */,
5358
B3E7B5881CC2AC0600A0062D /* <%= project.name %>.h */,
54-
B3E7B5891CC2AC0600A0062D /* <%= project.name %>.m */,
59+
B3E7B5891CC2AC0600A0062D /* <%= project.name %>.mm */,
5560
134814211AA4EA7D00B7C361 /* Products */,
5661
);
5762
sourceTree = "<group>";
@@ -95,6 +100,7 @@
95100
developmentRegion = English;
96101
hasScannedForEncodings = 0;
97102
knownRegions = (
103+
English,
98104
en,
99105
);
100106
mainGroup = 58B511D21A9E6C8500147676;
@@ -112,7 +118,8 @@
112118
isa = PBXSourcesBuildPhase;
113119
buildActionMask = 2147483647;
114120
files = (
115-
B3E7B58A1CC2AC0600A0062D /* <%= project.name %>.m in Sources */,
121+
5E46D8CD2428F78900513E24 /* example.cpp in Sources */,
122+
5E555C0D2413F4C50049A1A2 /* <%= project.name %>.mm in Sources */,
116123
);
117124
runOnlyForDeploymentPostprocessing = 0;
118125
};
@@ -216,7 +223,7 @@
216223
isa = XCBuildConfiguration;
217224
buildSettings = {
218225
HEADER_SEARCH_PATHS = (
219-
"$(inherited)",
226+
"$(inherited)",
220227
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
221228
"$(SRCROOT)/../../../React/**",
222229
"$(SRCROOT)/../../react-native/React/**",

templates/library/src/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { NativeModules } from 'react-native';
22

33
type <%= project.name %>Type = {
44
getDeviceName(): Promise<string>;
5+
<%if (project.useCpp==true) {%>
6+
multiply(a: number, b: number): Promise<number>;
7+
<%}%>
58
};
69

710
const { <%= project.name %> } = NativeModules;

0 commit comments

Comments
 (0)