Skip to content

Commit 5665a48

Browse files
authored
Merge pull request #148 from OpenBrickProtocolFoundation/only-define-version-in-one-place
Only define version in one place
2 parents fb1ecf4 + 3a932d4 commit 5665a48

File tree

6 files changed

+168
-30
lines changed

6 files changed

+168
-30
lines changed

.github/workflows/android.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Setup ninja
3434
run: |
3535
sudo apt-get update
36-
sudo apt-get install ninja-build
36+
sudo apt-get install ninja-build jq
3737
3838
- name: Setup JDK
3939
uses: actions/setup-java@v4

platforms/android/app/build.gradle

Lines changed: 158 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,77 @@ if (buildAsApplication) {
77
apply plugin: 'com.android.library'
88
}
99

10-
boolean existsABIDir(String abi) {
10+
/**
11+
* Internal helper function
12+
*/
13+
File getABIDir(String abi) {
1114
String path = "../../../../build-" + abi;
1215
File file = project.file(project.getLayout().getBuildDirectory().file(path));
13-
return file.exists();
16+
return file;
17+
}
18+
19+
/**
20+
* Internal helper function
21+
*/
22+
boolean existsABIDir(String abi) {
23+
File file = getABIDir(abi);
24+
return file.exists() && file.isDirectory();
25+
}
26+
27+
/**
28+
* Internal helper function
29+
*/
30+
static List<String> readInputStream(InputStream stream) {
31+
InputStreamReader reader = new InputStreamReader(stream);
32+
return reader.readLines()
33+
}
34+
35+
/**
36+
* Internal helper function
37+
*/
38+
static Tuple3<List<String>, List<String>, Integer> executePipeline(List<List<String>> commands) {
39+
List<ProcessBuilder> builders = commands.collect { it -> new ProcessBuilder(it) };
40+
41+
List<Process> processes = ProcessBuilder.startPipeline(builders);
42+
Process last = processes.get(processes.size() - 1);
43+
44+
int exitCode = last.waitFor();
45+
46+
List<String> stdout = readInputStream(last.getInputStream());
47+
List<String> stderr = readInputStream(last.getErrorStream());
48+
49+
return new Tuple3<List<String>, List<String>, Integer>(stdout, stderr, exitCode);
50+
}
51+
52+
/**
53+
* Internal helper function
54+
*/
55+
static boolean isValidVersion(String version) {
56+
if (version == null) {
57+
return false;
58+
}
59+
60+
List<String> parts = version.split("\\.")
61+
62+
if (parts.size() != 3) {
63+
return false;
64+
}
65+
66+
for (part in parts) {
67+
if (!part.isInteger()) {
68+
return false;
69+
}
70+
}
71+
72+
return true;
1473
}
1574

1675
/**
1776
* Read the Android ABI from user input.
1877
* supported ANDROID_ABIs are 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
19-
* @return return
78+
* @return List<String>
2079
*/
21-
def List getAndroidABI() {
80+
List getAndroidABIs() {
2281
String property = project.findProperty('ANDROID_ABI')
2382

2483
List<String> supportedABIs = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"];
@@ -49,7 +108,7 @@ def List getAndroidABI() {
49108

50109
for (abi in AbiFilters) {
51110
if (!existsABIDir(abi)) {
52-
throw new Exception('ERROR: build folder for abi \'' + abi + '\' doesn\'t exist: ' + file);
111+
throw new Exception("ERROR: build folder for abi '" + abi + "' doesn't exist: " + file);
53112
}
54113
}
55114

@@ -60,8 +119,99 @@ def List getAndroidABI() {
60119
return AbiFilters
61120
}
62121

122+
123+
/**
124+
* Determine the version
125+
* if you specify it explicitly, that will be used, otherwise meson introspect will be called
126+
* @return String
127+
*/
128+
String getVersion() {
129+
String property = project.findProperty('VERSION')
130+
131+
132+
if (property != null) {
133+
if (!isValidVersion(property)) {
134+
throw new Exception('User defined version is invalid: ' + property);
135+
}
136+
137+
return property;
138+
}
139+
140+
// auto detect
141+
142+
List<String> abis = getAndroidABIs();
143+
List<String> versions = new ArrayList<String>();
144+
145+
for (abi in abis) {
146+
File abiDir = getABIDir(abi);
147+
148+
Tuple3<List<String>, List<String>, Integer> versionResult = executePipeline(Arrays.asList(
149+
Arrays.asList("meson", "introspect", "--projectinfo", abiDir.getAbsolutePath()),
150+
Arrays.asList("jq", "-r", ".version")
151+
));
152+
153+
if (versionResult.getV3() != 0) {
154+
throw new Exception(
155+
'An error occured while trying to detect the version: process exited with exit code: ' +
156+
versionResult.getV3() +
157+
' and stderr:\n' +
158+
versionResult.getV2().join("\n")
159+
);
160+
}
161+
162+
if (versionResult.getV2() != null && !versionResult.getV2().isEmpty()) {
163+
throw new Exception('An error occured while trying to detect the version (code 1): ' + versionResult.getV2().join("\n"));
164+
}
165+
166+
if (versionResult.getV1() == null || versionResult.getV1().size() != 1) {
167+
throw new Exception('An error occured while trying to detect the version (code 2): ' + versionResult.getV1().join("\n"));
168+
}
169+
170+
String version = versionResult.getV1()[0];
171+
172+
if (!isValidVersion(version)) {
173+
throw new Exception("Auto detection of version returned invalid version: '" + version + "'");
174+
}
175+
176+
for (version1 in versions) {
177+
if (version != version1) {
178+
throw new Exception("Recievd two versions, that didn't match: " + version1 + " != " + version);
179+
}
180+
}
181+
182+
versions.add(version);
183+
184+
}
185+
186+
187+
if (versions.size() == 0) {
188+
throw new Exception("ERROR: at least one version has to be detected (at least one abi has to be returend by 'getAndroidABIs()')");
189+
}
190+
191+
// we guarantee, that every string in there is the same, and that it has at least one entry
192+
return versions[0];
193+
194+
}
195+
196+
List<String> abisToUse = getAndroidABIs()
197+
String versionString = getVersion()
198+
199+
System.out.printf("DEBUG: Using abis: %s%n", abisToUse.join(", "))
200+
System.out.printf("DEBUG: Using version: %s%n", versionString)
201+
202+
java {
203+
toolchain {
204+
languageVersion = JavaLanguageVersion.of(21)
205+
}
206+
}
207+
63208
android {
64-
compileSdk 34
209+
compileOptions {
210+
sourceCompatibility JavaVersion.VERSION_21
211+
targetCompatibility JavaVersion.VERSION_21
212+
}
213+
214+
compileSdkVersion 34
65215
ndkVersion "26.3.11579264"
66216
defaultConfig {
67217
if (buildAsApplication) {
@@ -70,7 +220,7 @@ android {
70220
minSdkVersion 21
71221
targetSdkVersion 34
72222
versionCode 5
73-
versionName "0.5.4"
223+
versionName(versionString)
74224
}
75225
buildTypes {
76226
release {
@@ -119,7 +269,7 @@ android {
119269
// Resets the list of ABIs for Gradle to create APKs for to none.
120270
reset()
121271
// Specifies a list of ABIs for Gradle to create APKs for.
122-
include(*getAndroidABI())
272+
include(*abisToUse)
123273
// Specifies that you don't want to also generate a universal APK that includes all ABIs.
124274
universalApk false
125275
}

platforms/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ buildscript {
66
google()
77
}
88
dependencies {
9-
classpath 'com.android.tools.build:gradle:8.3.1'
9+
classpath 'com.android.tools.build:gradle:8.4.0'
1010

1111
// NOTE: Do not place your application dependencies here; they belong
1212
// in the individual module build.gradle files
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Tue Jan 02 02:01:38 CET 2024
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

platforms/build-switch.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ libnx='$LIBNX'
101101
102102
APP_NAME = 'oopetris'
103103
APP_AUTHOR = 'coder2k'
104-
APP_VERSION = '0.5.4'
104+
APP_VERSION = true
105105
106106
USE_NACP = true
107107

platforms/switch/meson.build

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
21
## get the options object and "unpack" it
32

43
switch_exe_name = switch_options[0]
54
switch_src_files = switch_options[1]
65
switch_deps = switch_options[2]
76

8-
97
# libraries
108

119
switch_dependencies = [
@@ -32,7 +30,6 @@ switch_dependencies_native = [
3230
'SDL2main',
3331
]
3432

35-
3633
foreach dep : switch_dependencies
3734
switch_deps += dependency(
3835
dep,
@@ -56,8 +53,6 @@ foreach dep : switch_dependencies_native
5653
)
5754
endforeach
5855

59-
60-
6156
## compilation
6257

6358
switch_elf_file = build_target(
@@ -76,7 +71,6 @@ use_nacp = ['true', 'True', '1', true].contains(
7671
meson.get_external_property('USE_NACP', ''),
7772
)
7873

79-
8074
elf2nro = find_program('elf2nro')
8175
# executable input elf file, output nro file
8276
NRO_FLAGS = [elf2nro, switch_elf_file.full_path(), switch_exe_name + '.nro']
@@ -92,23 +86,23 @@ if use_nacp
9286
APP_NAME = meson.get_external_property('APP_NAME', switch_exe_name)
9387
NACP_FLAGS += APP_NAME
9488

95-
9689
APP_AUTHOR = meson.get_external_property('APP_AUTHOR', '')
9790
if APP_AUTHOR == ''
9891
error('If USE_NACP is set, you have to provide an APP_AUTHOR')
9992
endif
10093
NACP_FLAGS += APP_AUTHOR
10194

10295
APP_VERSION = meson.get_external_property('APP_VERSION', '')
96+
if APP_VERSION == true
97+
APP_VERSION = meson.project_version()
98+
endif
99+
103100
if APP_VERSION == ''
104101
error('If USE_NACP is set, you have to provide an APP_VERSION')
105102
endif
106103
NACP_FLAGS += APP_VERSION
107104

108-
NACP_FLAGS += (
109-
switch_exe_name + '.nacp' # outfile
110-
)
111-
105+
NACP_FLAGS += (switch_exe_name + '.nacp')
112106

113107
APP_TITLEID = meson.get_external_property('APP_TITLEID', '')
114108

@@ -117,8 +111,7 @@ if use_nacp
117111
NACP_FLAGS += '--titleid=' + APP_TITLEID
118112
endif
119113

120-
121-
# nacptool --create <name> <author> <version> <switch_exe_name>.nacp
114+
# nacptool --create <name> <author> <version> <switch_exe_name>.nacp
122115
# optional: --titleid=<titleID>
123116
nacp_file = custom_target(
124117
switch_exe_name + '.nacp',
@@ -129,7 +122,6 @@ if use_nacp
129122
NRO_FLAGS += '--nacp=' + switch_exe_name + '.nacp'
130123
NRO_DEPS += nacp_file
131124

132-
133125
endif
134126

135127
LIBNX = meson.get_external_property('libnx', '')
@@ -145,16 +137,12 @@ if not fs.is_absolute(APP_ICON)
145137
APP_ICON = meson.project_source_root() / APP_ICON
146138
endif
147139

148-
149140
if not fs.exists(APP_ICON)
150141
error('APP_ICON should exist, but doesn\'t: \'' + APP_ICON + '\'')
151142
endif
152143

153-
154-
155144
NRO_FLAGS += '--icon=' + APP_ICON
156145

157-
158146
APP_ROMFS = meson.get_external_property('APP_ROMFS', '')
159147

160148
if APP_ROMFS != ''

0 commit comments

Comments
 (0)