Compare commits
21 Commits
1.6.1
...
release-ed
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c070524f06 | ||
![]() |
74e75bf916 | ||
![]() |
fa567cb536 | ||
![]() |
9cf7d70c65 | ||
![]() |
63f6870d6a | ||
![]() |
dd6be52e50 | ||
![]() |
b03bfd5f53 | ||
![]() |
f1cdbacdbf | ||
![]() |
e6da4c2926 | ||
![]() |
ebf7841a86 | ||
![]() |
77ad3358fd | ||
![]() |
14a18fc993 | ||
![]() |
686158e24b | ||
![]() |
2b21d7b78f | ||
![]() |
e9da1041f5 | ||
![]() |
e1dbd4ac08 | ||
![]() |
ecd387b901 | ||
![]() |
c87daec905 | ||
![]() |
0d0ea58276 | ||
![]() |
a0bfdad1a9 | ||
![]() |
b0cffca0ab |
116
BUILD.md
Normal file
116
BUILD.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
Building an I2P Easy-Install Bundle for Mac
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
This documents building the I2P Easy-Install for Mac end-to-end, including the
|
||||||
|
set up, configuration, and maintenance of a build environment.
|
||||||
|
|
||||||
|
Setting up a Java SDK manager
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Unlike many popular Linux distributions, Mac OSX does not have a built-in way
|
||||||
|
of switching between Java versions. There are several third-party tools for
|
||||||
|
doing this, including `sdkman` and `asdf`. After evaluation, I found
|
||||||
|
sdkman to be the most complete and easy to use. Installation instructions are
|
||||||
|
available here:
|
||||||
|
|
||||||
|
- https://sdkman.io/install
|
||||||
|
|
||||||
|
Since it uses a curlpipe to install, please be sure to pay attention to the
|
||||||
|
content of the install script.
|
||||||
|
|
||||||
|
- https://get.sdkman.io
|
||||||
|
|
||||||
|
After you follow the install instructions, you will be able to fetch java SDKs
|
||||||
|
and automatically configure your `JAVA_HOME`.
|
||||||
|
|
||||||
|
Currently, bundles are built with OpenJDK 19.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sdk install java 19.0.1-open
|
||||||
|
sdk use java 19.0.1-open
|
||||||
|
```
|
||||||
|
|
||||||
|
Will automatically set up your OpenJDK 19.
|
||||||
|
|
||||||
|
If you do not wish to use an SDK manager, or you with to use a different SDK
|
||||||
|
manager, this [Stack Overflow link](https://stackoverflow.com/questions/52524112/how-do-i-install-java-on-mac-osx-allowing-version-switching)
|
||||||
|
shows every option in detail.
|
||||||
|
|
||||||
|
Setting up Brew and resolving build dependencies
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
There are also a number of build dependencies for I2P which you will need to
|
||||||
|
keep up to date. This is aided by the use of the brew package manager. Obtain
|
||||||
|
`brew` by installing it according to the instructions here:
|
||||||
|
|
||||||
|
- https://brew.sh/
|
||||||
|
|
||||||
|
Once Brew is finished installing, install the I2P build dependencies.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install ant gettext gradle
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember to run `brew update` and `brew upgrade ant gettext gradle` before
|
||||||
|
rebuilding I2P.
|
||||||
|
|
||||||
|
Building the I2P Router Dependencies and the Package
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
Once you have all that installed you're ready to build the core I2P router
|
||||||
|
libraries and package the application. This can all be automated with the use
|
||||||
|
of `build.sh`. In order to do this successfully, you need to be able to sign
|
||||||
|
OSX packages, using a certificate which you obtain from Apple itself. Obtaining
|
||||||
|
that certificate is outside the scope of this document primarily because I do
|
||||||
|
not have the ability to obtain such a certificate without sharing my identity
|
||||||
|
with Apple.
|
||||||
|
|
||||||
|
- https://developer.apple.com/support/certificates/
|
||||||
|
- https://developer.apple.com/documentation/appstoreconnectapi/certificates
|
||||||
|
|
||||||
|
In order to configure your release environment, you must set the following
|
||||||
|
environment variables:
|
||||||
|
|
||||||
|
- `I2P_SIGNER` should be the [Apple Developer ID of the signer](https://developer.apple.com/support/developer-id/)
|
||||||
|
- `I2P_CODE_SIGNER` should be the Apple Developer ID for Code Signing of the signer(Usually find this with `security find-identity -v -p codesigning`)
|
||||||
|
- `I2P_VERSION` should be the version of the I2P router that you want to use
|
||||||
|
- `I2P_BUILD_NUMBER` should be an integer greater than `0`.
|
||||||
|
|
||||||
|
Ensure you have a copy of `i2p.i2p` checked out adjacent to the
|
||||||
|
`i2p-jpackage-mac` directory, in the same parent. If this is your first time
|
||||||
|
building the jpackage, run the following command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://i2pgit.org/i2p-hackers/i2p.i2p
|
||||||
|
```
|
||||||
|
|
||||||
|
Change to the `i2p.i2p` directory and check out the release branch you want to
|
||||||
|
build a package for, e.g. `i2p-1.9.0`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ../i2p.i2p
|
||||||
|
git pull --tags
|
||||||
|
git checkout i2p-1.9.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Now that you have the right branch, clean and rebuild the core library:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ant clean preppkg-osx-only
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, change back to the `i2p-jpackage-mac` directory:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ../i2p-jpackage-mac
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, run the `build.sh` script to generate the `.dmg` file.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Creating a new release
|
||||||
|
----------------------
|
||||||
|
|
14
README.md
14
README.md
@@ -19,7 +19,7 @@ JPackage scripts for packaging I2P on a Mac.
|
|||||||
|
|
||||||
In order to build an AppBundle that can work from anywhere, it is necessary to use a dedicated main class which determines the current working directory and sets `i2p.dir.base` to the correct location inside the AppBundle. Therefore the `build.sh` script:
|
In order to build an AppBundle that can work from anywhere, it is necessary to use a dedicated main class which determines the current working directory and sets `i2p.dir.base` to the correct location inside the AppBundle. Therefore the `build.sh` script:
|
||||||
|
|
||||||
1. Compiles the custom main clas and puts it in a `launcher.jar`
|
1. Compiles the custom main class and puts it in a `launcher.jar`
|
||||||
1. Invokes JPackage with the `--app-image` switch to create the directory structure of the bundle
|
1. Invokes JPackage with the `--app-image` switch to create the directory structure of the bundle
|
||||||
1. Copies the contents of `../i2p.i2p/pkg-temp` inside the AppBundle, except for the `jars` directory
|
1. Copies the contents of `../i2p.i2p/pkg-temp` inside the AppBundle, except for the `jars` directory
|
||||||
1. Signs the AppBundle
|
1. Signs the AppBundle
|
||||||
@@ -30,10 +30,16 @@ In order to build an AppBundle that can work from anywhere, it is necessary to u
|
|||||||
1. You need an "app-specific password" which you can create at https://appleid.apple.com
|
1. You need an "app-specific password" which you can create at https://appleid.apple.com
|
||||||
2. Execute
|
2. Execute
|
||||||
```
|
```
|
||||||
xcrun altool --eval-app --primary-bundle-id net.i2p.router -u <your Apple id> -f <name of the .dmg file>
|
xcrun notarytool store-credentials "$AC_PASSWORD"
|
||||||
|
--apple-id "$AC_USERNAME"
|
||||||
|
--team-id "$WWDRTeamID"
|
||||||
|
--password "$secret_2FA_password"
|
||||||
```
|
```
|
||||||
This will ask you for the password you generated in step 1 and will return a long UUID string you can use to check the progress.
|
- In this example command:
|
||||||
|
- `AC_PASSWORD` is the name of the credentials config.
|
||||||
|
- `AC_USERNAME` is the username of the Apple Account.
|
||||||
|
- `WWDRTeamID` is the developer/team ID available from the Apple Account.
|
||||||
|
- `secret_2FA_Password` is the app-specific password you set up in the first step.
|
||||||
3. Periodically execute the following to check the progress of the notarisation:
|
3. Periodically execute the following to check the progress of the notarisation:
|
||||||
```
|
```
|
||||||
xcrun altool --eval-info <the long UUID string> -u <your Apple id>
|
xcrun altool --eval-info <the long UUID string> -u <your Apple id>
|
||||||
|
70
build.sh
70
build.sh
@@ -1,6 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ -f config.sh ]; then
|
||||||
|
. config.sh
|
||||||
|
fi
|
||||||
|
|
||||||
# old javas output version to stderr and don't support --version
|
# old javas output version to stderr and don't support --version
|
||||||
JAVA=$(java --version 2>&1 | tr -d 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n' | cut -d ' ' -f 2 | cut -d '.' -f 1 | tr -d '\n\t ')
|
JAVA=$(java --version 2>&1 | tr -d 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n' | cut -d ' ' -f 2 | cut -d '.' -f 1 | tr -d '\n\t ')
|
||||||
|
|
||||||
@@ -16,8 +20,7 @@ if [ "$JAVA" -lt "16" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${I2P_SIGNER}" ]; then
|
if [ -z "${I2P_SIGNER}" ]; then
|
||||||
echo "I2P_SIGNER variable not set, can't sign. Aborting..."
|
echo "I2P_SIGNER variable not set, can't sign. Script will terminate after unsigned app-image generation"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z ${I2P_VERSION} ]; then
|
if [ -z ${I2P_VERSION} ]; then
|
||||||
@@ -30,11 +33,16 @@ if [ -z ${I2P_BUILD_NUMBER} ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z ${JAVA_HOME} ]; then
|
||||||
|
JAVA_HOME=$(/usr/libexec/java_home)
|
||||||
|
fi
|
||||||
|
|
||||||
echo "JAVA_HOME is $JAVA_HOME"
|
echo "JAVA_HOME is $JAVA_HOME"
|
||||||
|
|
||||||
echo "cleaning"
|
echo "cleaning"
|
||||||
./clean.sh
|
./clean.sh
|
||||||
|
|
||||||
|
ARCH=$(uname -m)
|
||||||
HERE=$PWD
|
HERE=$PWD
|
||||||
I2P_JARS=$HERE/../i2p.i2p/pkg-temp/lib
|
I2P_JARS=$HERE/../i2p.i2p/pkg-temp/lib
|
||||||
I2P_PKG=$HERE/../i2p.i2p/pkg-temp
|
I2P_PKG=$HERE/../i2p.i2p/pkg-temp
|
||||||
@@ -58,17 +66,25 @@ cd ..
|
|||||||
echo "compiling native lib"
|
echo "compiling native lib"
|
||||||
cc -v -Wl,-lobjc -mmacosx-version-min=10.9 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Ic -o build/libMacLauncher.jnilib -shared c/net_i2p_router_MacLauncher.c
|
cc -v -Wl,-lobjc -mmacosx-version-min=10.9 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Ic -o build/libMacLauncher.jnilib -shared c/net_i2p_router_MacLauncher.c
|
||||||
|
|
||||||
echo "signing jbigi libs"
|
if [ -z $I2P_SIGNER ]; then
|
||||||
mkdir jbigi
|
echo "I2P_SIGNER is unset, not proceeding to sign jbigi libs"
|
||||||
cp $I2P_JARS/jbigi.jar jbigi
|
cp $I2P_JARS/jbigi.jar build
|
||||||
cd jbigi
|
else
|
||||||
unzip jbigi.jar
|
echo "signing jbigi libs"
|
||||||
for lib in *.jnilib; do
|
mkdir jbigi
|
||||||
codesign --force -s $I2P_SIGNER -v $lib
|
cp $I2P_JARS/jbigi.jar jbigi
|
||||||
jar uf jbigi.jar $lib
|
cd jbigi
|
||||||
done
|
unzip jbigi.jar
|
||||||
cp jbigi.jar ../build
|
for lib in *.jnilib; do
|
||||||
cd ..
|
codesign --force -s $I2P_SIGNER -v $lib
|
||||||
|
jar uf jbigi.jar $lib
|
||||||
|
done
|
||||||
|
cp jbigi.jar ../build
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
I2P_VERSION=$(java -cp build/router.jar net.i2p.router.RouterVersion | sed "s/.*: //" | head -n 1)
|
I2P_VERSION=$(java -cp build/router.jar net.i2p.router.RouterVersion | sed "s/.*: //" | head -n 1)
|
||||||
echo "preparing to invoke jpackage for I2P version $I2P_VERSION build $I2P_BUILD_NUMBER"
|
echo "preparing to invoke jpackage for I2P version $I2P_VERSION build $I2P_BUILD_NUMBER"
|
||||||
@@ -76,6 +92,7 @@ echo "preparing to invoke jpackage for I2P version $I2P_VERSION build $I2P_BUILD
|
|||||||
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P.icns
|
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P.icns
|
||||||
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P-volume.icns
|
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P-volume.icns
|
||||||
cp $I2P_PKG/LICENSE.txt build
|
cp $I2P_PKG/LICENSE.txt build
|
||||||
|
cat resources/License-JRE-snippet.txt >> build/LICENSE.txt
|
||||||
cp resources/I2P-background.tiff build
|
cp resources/I2P-background.tiff build
|
||||||
|
|
||||||
cp resources/Info.plist.template build/Info.plist
|
cp resources/Info.plist.template build/Info.plist
|
||||||
@@ -103,13 +120,34 @@ for i in i2prouter lib locale man wrapper.config eepget runplain.sh postinstall.
|
|||||||
rm -rf I2P.app/Contents/Resources/$i
|
rm -rf I2P.app/Contents/Resources/$i
|
||||||
done
|
done
|
||||||
cp $HERE/resources/GPLv2+CE.txt I2P.app/Contents/Resources/licenses/LICENSE-JRE.txt
|
cp $HERE/resources/GPLv2+CE.txt I2P.app/Contents/Resources/licenses/LICENSE-JRE.txt
|
||||||
|
cp $I2P_PKG/licenses/* I2P.app/Contents/Resources/licenses/
|
||||||
cp $HERE/build/libMacLauncher.jnilib I2P.app/Contents/Resources
|
cp $HERE/build/libMacLauncher.jnilib I2P.app/Contents/Resources
|
||||||
cp $HERE/resources/router.config I2P.app/Contents/Resources
|
if [ $ARCH == "arm64" ]; then
|
||||||
|
cp $HERE/resources/router.config.arm64 I2P.app/Contents/Resources/router.config
|
||||||
|
else
|
||||||
|
cp $HERE/resources/router.config I2P.app/Contents/Resources
|
||||||
|
fi
|
||||||
cp $HERE/resources/*.crt I2P.app/Contents/Resources/certificates/router
|
cp $HERE/resources/*.crt I2P.app/Contents/Resources/certificates/router
|
||||||
|
|
||||||
|
if [ -z $I2P_SIGNER ]; then
|
||||||
|
echo "I2P_SIGNER is unset, not proceeding to signing phase"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "signing the runtime libraries"
|
echo "signing the runtime libraries"
|
||||||
find I2P.app -name *.dylib -exec codesign --force -s $I2P_SIGNER -v '{}' \;
|
|
||||||
find I2P.app -name *.jnilib -exec codesign --force -s $I2P_SIGNER -v '{}' \;
|
if [ $I2P_CODE_SIGNER = signer@mail.i2p ]; then
|
||||||
|
echo "I2P_CODE_SIGNER is unset, not signing dylibs or jnilibs, app will fail notarization"
|
||||||
|
else
|
||||||
|
find I2P.app -name *.dylib -exec codesign --force -s $I2P_CODE_SIGNER -v '{}' \;
|
||||||
|
find I2P.app -name *.jnilib -exec codesign --force -s $I2P_CODE_SIGNER -v '{}' \;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $I2P_SIGNER = signer@mail.i2p ]; then
|
||||||
|
echo "I2P_SIGNER is unset, not proceeding to signing phase"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
echo "signing the bundle"
|
echo "signing the bundle"
|
||||||
codesign --force -d --deep -f \
|
codesign --force -d --deep -f \
|
||||||
|
26
config.sh
Normal file
26
config.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#! /usr/bin/env sh
|
||||||
|
|
||||||
|
if [ -z $I2P_SIGNER ]; then
|
||||||
|
# This is the team ID of the Apple account associated with the app. It is used to sign the DMG.
|
||||||
|
# it is a unique ID which is a short, random-looking string.
|
||||||
|
I2P_SIGNER=signer@mail.i2p
|
||||||
|
fi
|
||||||
|
if [ -z $I2P_CODE_SIGNER ]; then
|
||||||
|
# This is the code signing ID of the team associated with the Apple Account. it is used to sign the libraries.
|
||||||
|
# it is a unique ID which is a short, random-looking string.
|
||||||
|
I2P_SIGNER=signer@mail.i2p
|
||||||
|
fi
|
||||||
|
if [ -z $I2P_VERSION ]; then
|
||||||
|
I2P_VERSION=2.0.0
|
||||||
|
fi
|
||||||
|
if [ -z $I2P_BUILD_NUMBER ]; then
|
||||||
|
I2P_BUILD_NUMBER=1
|
||||||
|
fi
|
||||||
|
# Uncomment/Edit this line to include the signer in the config file
|
||||||
|
# I2P_SIGNER=signer@mail.i2p
|
||||||
|
# Uncomment/Edit this line to include the code signer in the config file
|
||||||
|
# I2P_CODE_SIGNER=signer@mail.i2p
|
||||||
|
# Uncomment/Edit this line to include the version number in the config file
|
||||||
|
# I2P_VERSION=2.0.0
|
||||||
|
# Uncomment/Edit this line to include the build number in the config file
|
||||||
|
# I2P_BUILD_NUMBER=1
|
@@ -60,8 +60,13 @@ public class MacLauncher {
|
|||||||
sleep(1000);
|
sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// then wait for ClientAppManager
|
||||||
|
ClientAppManager cam;
|
||||||
|
while ((cam = ctx.clientAppManager()) == null) {
|
||||||
|
sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
// then wait for the update manager
|
// then wait for the update manager
|
||||||
ClientAppManager cam = ctx.clientAppManager();
|
|
||||||
UpdateManager um;
|
UpdateManager um;
|
||||||
while ((um = (UpdateManager) cam.getRegisteredApp(UpdateManager.APP_NAME)) == null) {
|
while ((um = (UpdateManager) cam.getRegisteredApp(UpdateManager.APP_NAME)) == null) {
|
||||||
sleep(1000);
|
sleep(1000);
|
||||||
|
11
resources/License-JRE-snippet.txt
Normal file
11
resources/License-JRE-snippet.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Java Runtime Environment
|
||||||
|
------------------------
|
||||||
|
This Mac bundle comes with a built-in Java Runtime
|
||||||
|
Environment which is licensed under GPLv2+Classpath
|
||||||
|
exception.
|
||||||
|
|
||||||
|
You can find the text of this license in
|
||||||
|
Source tree - resources/GPLv2+CE.txt
|
||||||
|
I2P.app bundle - Contents/Resources/licenses/LICENSE-JRE.txt
|
2
resources/router.config.arm64
Normal file
2
resources/router.config.arm64
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
router.newsURL=http://tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq.b32.i2p/mac-arm64/stable/news.su3
|
||||||
|
router.backupNewsURL=http://dn3tvalnjz432qkqsvpfdqrwpqkw3ye4n4i2uyfr4jexvo3sp5ka.b32.i2p/news/mac-arm64/stable/news.su3
|
Reference in New Issue
Block a user