====== Compilation d'eggdrop avec Tcl 9 ======
Nota: Ce tutoriel a été écrit par Te[u]K, qui le tiendra à jour. Il explique comment compiler et exécuter Eggdrop 1.10.1 avec Tcl 9.0.3, TclTLS 2.0, Tcllib 2.0 et OpenSSL 3.6.1 sur Debian
===== Introduction =====
Si vous maintenez encore des scripts Tcl historiques autour d'Eggdrop, vous avez sans doute déjà rencontré le même mur: les environnements modernes évoluent, les bibliothèques TLS changent, les versions système de Tcl ne collent plus forcément à ce que vos scripts attendent, et les vieux montages //qui marchaient avant// deviennent fragiles.
L'objectif de ce guide est de proposer une base propre, reproductible et moderne pour faire tourner **Eggdrop 1.10.1** avec **OpenSSL 3.6.1**, **Tcl 9.0.3**, **TclTLS 2.0** et **Tcllib 2.0** sur Debian, en évitant autant que possible les dépendances implicites au système.
L'idée n'est pas seulement de faire démarrer le bot, mais de construire une pile cohérente, explicite, et plus facile à déboguer quand on commence à réinjecter de vieux scripts Tcl, parfois écrits il y a très longtemps, parfois testés dans des environnements très différents.
Ce guide repose sur une procédure réellement validée en labo, avec des pièges concrets rencontrés en route.
===== Pourquoi ne pas utiliser simplement les versions système ? =====
Sur une Debian récente, vous avez déjà :
- un OpenSSL système,
- parfois un Tcl système,
- et de quoi compiler Eggdrop.
Mais dans la pratique, ce n’est pas assez propre si vous voulez :
- figer exactement les versions,
- éviter les surprises de linkage,
- comparer plusieurs environnements,
- ou reproduire un comportement au plus près d’une pile cible donnée.
Dans ce guide, on choisit donc de tout isoler sous :
```bash
/opt/eggdrop-lab
```
avec une séparation claire entre :
- les **sources**
- les **bibliothèques privées**
- le **runtime Eggdrop**
- l’**instance réelle du bot**
---
## Pourquoi c’est important pour les scripts Tcl historiques sous Eggdrop
C’est probablement la partie la plus importante du sujet.
Beaucoup de scripts Tcl historiques pour Eggdrop reposent sur des hypothèses implicites :
- présence de certains packages Tcl dans `auto_path`
- comportement d’une vieille pile TLS
- wrappers HTTP artisanaux
- dépendances à `tcllib`
- différences de comportement entre Tcl 8.x et Tcl 9
- environnement Windows/Cygwin/Windrop différent d’un Linux moderne
Quand on remet ces scripts dans un contexte moderne, le vrai problème n’est pas seulement “est-ce qu’Eggdrop démarre ?â€.
Le vrai problème est souvent :
- **est-ce que les bons packages Tcl sont réellement chargés ?**
- **est-ce que `tls` utilise bien le bon OpenSSL ?**
- **est-ce qu’on dépend involontairement des libs système ?**
- **est-ce qu’un vieux script échoue à cause de son code, ou à cause de la pile runtime ?**
Avec une pile maîtrisée comme celle-ci, vous réduisez énormément le bruit de fond :
- moins d’ambiguïtés
- moins de faux diagnostics
- plus de chances d’isoler les vrais problèmes de compatibilité dans les scripts
Autrement dit :
ce guide n’est pas seulement utile pour “installer Eggdropâ€, il est surtout utile pour **travailler proprement sur des scripts Tcl historiques dans un environnement moderne**.
---
## Pile logicielle cible
Ce guide vise explicitement cette pile :
- **OpenSSL 3.6.1**
- **Tcl 9.0.3**
- **TclTLS 2.0**
- **Tcllib 2.0**
- **Eggdrop 1.10.1**
---
## Arborescence de travail recommandée
On utilisera cette base :
```bash
/opt/eggdrop-lab/
├── src
├── openssl361
├── tcl903
└── eggdrop1101
```
Et pour l’instance du bot :
```bash
/home/eggbot/EggdropBot
```
Dans ce guide, on utilise des variables shell pour éviter les chemins codés en dur.
---
## Variables utilisées dans ce guide
```bash
BOT_USER="eggbot"
BOT_HOME="/home/$BOT_USER"
BOT_INSTANCE="EggdropBot"
OPENSSL_HOME="/opt/eggdrop-lab/openssl361"
TCL_HOME="/opt/eggdrop-lab/tcl903"
SRC_HOME="/opt/eggdrop-lab/src"
```
### Remarque importante sur `BOT_USER`
Choisissez ce nom avec soin.
Ce n’est pas juste un détail cosmétique. Selon votre environnement, il peut avoir un impact sur :
- la lisibilité des chemins
- les ownerships
- les logs
- les noms de services
- et parfois, indirectement, ce qui apparaît côté **identd / ident**
Évitez donc un nom improvisé ou trop personnel si vous comptez publier votre procédure ou réutiliser la structure ailleurs.
---
## Dépendances de build
En root :
```bash
apt update
apt install -y \
build-essential \
pkg-config \
autoconf \
automake \
libtool \
make \
gcc \
g++ \
libc6-dev \
zlib1g-dev \
libbz2-dev \
wget \
curl \
ca-certificates \
git \
unzip \
xz-utils
```
On n’installe volontairement **aucun Tcl système** via Debian.
---
## Création de l’arborescence
```bash
mkdir -p /opt/eggdrop-lab/src
mkdir -p /opt/eggdrop-lab/openssl361
mkdir -p /opt/eggdrop-lab/tcl903
mkdir -p /opt/eggdrop-lab/eggdrop1101
```
---
## Téléchargement des sources
```bash
cd /opt/eggdrop-lab/src
wget -O openssl-3.6.1.tar.gz \
"https://github.com/openssl/openssl/releases/download/openssl-3.6.1/openssl-3.6.1.tar.gz"
wget -O tcl9.0.3-src.tar.gz \
"https://prdownloads.sourceforge.net/tcl/tcl9.0.3-src.tar.gz"
wget -O tcltls-2.0-src.tar.gz \
"https://core.tcl-lang.org/tcltls/uv/tcltls-2.0-src.tar.gz"
wget -O eggdrop-1.10.1.tar.gz \
"https://ftp.eggheads.org/pub/eggdrop/source/1.10/eggdrop-1.10.1.tar.gz"
wget -O tcllib-2.0.tar.gz \
"https://core.tcl-lang.org/tcllib/tarball/tcllib-2.0.tar.gz?r=tcllib-2-0"
```
---
## Compiler OpenSSL 3.6.1
```bash
cd "$SRC_HOME"
tar xzf openssl-3.6.1.tar.gz
cd openssl-3.6.1
./Configure \
--prefix="$OPENSSL_HOME" \
--openssldir="$OPENSSL_HOME/ssl" \
shared \
zlib \
linux-x86_64 \
"-Wl,-rpath,$OPENSSL_HOME/lib64" \
"-Wl,-rpath,$OPENSSL_HOME/lib"
make -j"$(nproc)"
make install_sw
```
### Vérification
```bash
LD_LIBRARY_PATH="$OPENSSL_HOME/lib64:$OPENSSL_HOME/lib" \
"$OPENSSL_HOME/bin/openssl" version -a
```
---
## Compiler Tcl 9.0.3
```bash
cd "$SRC_HOME"
tar xzf tcl9.0.3-src.tar.gz
cd tcl9.0.3/unix
./configure --prefix="$TCL_HOME"
make -j"$(nproc)"
make install
ln -sf "$TCL_HOME/bin/tclsh9.0" "$TCL_HOME/bin/tclsh"
```
### Vérification
```bash
"$TCL_HOME/bin/tclsh9.0" <<< 'puts [info patchlevel]'
```
---
## Compiler TclTLS 2.0
Pour éviter toute ambiguïté sur le nom du répertoire extrait, on utilise une méthode déterministe :
```bash
cd "$SRC_HOME"
TLS_TARBALL="tcltls-2.0-src.tar.gz"
TLS_SRCDIR="$(tar tzf "$TLS_TARBALL" | head -1 | cut -d/ -f1)"
tar xzf "$TLS_TARBALL"
cd "$TLS_SRCDIR"
make distclean 2>/dev/null || true
export PKG_CONFIG_PATH="$OPENSSL_HOME/lib64/pkgconfig:$OPENSSL_HOME/lib/pkgconfig"
export LD_LIBRARY_PATH="$OPENSSL_HOME/lib64:$OPENSSL_HOME/lib:$TCL_HOME/lib"
./configure \
--prefix="$TCL_HOME" \
--with-tcl="$TCL_HOME/lib" \
--with-tclinclude="$TCL_HOME/include" \
CPPFLAGS="-I$OPENSSL_HOME/include -I$TCL_HOME/include" \
LDFLAGS="-L$OPENSSL_HOME/lib64 -L$OPENSSL_HOME/lib -L$TCL_HOME/lib -Wl,-rpath,$OPENSSL_HOME/lib64 -Wl,-rpath,$OPENSSL_HOME/lib -Wl,-rpath,$TCL_HOME/lib"
make -j"$(nproc)"
make install
```
### Vérification
```bash
export TCLLIBPATH="$TCL_HOME/lib"
export LD_LIBRARY_PATH="$OPENSSL_HOME/lib64:$OPENSSL_HOME/lib:$TCL_HOME/lib"
"$TCL_HOME/bin/tclsh9.0" <<'EOF'
puts "Tcl=[info patchlevel]"
puts "tls=[package require tls]"
EOF
```
---
## Compiler Tcllib 2.0
Ici, il y a un point important.
Pour éviter une erreur liée à **Critcl** et à la partie optionnelle **TcllibC**, on utilise :
```bash
make install-tcl
```
et non `make install`.
```bash
cd "$SRC_HOME"
TCLLIB_TARBALL="tcllib-2.0.tar.gz"
TCLLIB_SRCDIR="$(tar tzf "$TCLLIB_TARBALL" | head -1 | cut -d/ -f1)"
tar xzf "$TCLLIB_TARBALL"
cd "$TCLLIB_SRCDIR"
./configure --prefix="$TCL_HOME"
make -j"$(nproc)"
make install-tcl
```
### Vérification
```bash
export TCLLIBPATH="$TCL_HOME/lib $TCL_HOME/lib/tcllib2.0"
export LD_LIBRARY_PATH="$OPENSSL_HOME/lib64:$OPENSSL_HOME/lib:$TCL_HOME/lib"
"$TCL_HOME/bin/tclsh9.0" <<'EOF'
puts "Tcl=[info patchlevel]"
puts "tls=[package require tls]"
puts "TCLLIBPATH=$::env(TCLLIBPATH)"
puts "auto_path=$auto_path"
foreach p {md5 sha1 struct::list uri base64 json} {
if {[catch {package require $p} v]} {
puts "$p => ERR: $v"
} else {
puts "$p => OK: $v"
}
}
EOF
```
---
## Créer l’utilisateur runtime
En root :
```bash
useradd -m -d "$BOT_HOME" -s /bin/bash "$BOT_USER"
passwd "$BOT_USER"
chown -R "$BOT_USER:$BOT_USER" /opt/eggdrop-lab
```
---
## Compiler Eggdrop 1.10.1 sous l’utilisateur non privilégié
Passer sous l’utilisateur :
```bash
su - "$BOT_USER"
```
Puis reposer les variables :
```bash
BOT_USER="eggbot"
BOT_HOME="/home/$BOT_USER"
BOT_INSTANCE="EggdropBot"
OPENSSL_HOME="/opt/eggdrop-lab/openssl361"
TCL_HOME="/opt/eggdrop-lab/tcl903"
SRC_HOME="/opt/eggdrop-lab/src"
```
### Nettoyer toute ancienne instance staging
C’est important, notamment pour éviter les vieux liens symboliques oubliés.
```bash
rm -rf "$BOT_HOME/$BOT_INSTANCE"
mkdir -p "$BOT_HOME/$BOT_INSTANCE"
```
### Réextraire Eggdrop proprement
```bash
cd "$SRC_HOME"
EGGDROP_TARBALL="eggdrop-1.10.1.tar.gz"
EGGDROP_SRCDIR="$(tar tzf "$EGGDROP_TARBALL" | head -1 | cut -d/ -f1)"
rm -rf "$EGGDROP_SRCDIR"
tar xzf "$EGGDROP_TARBALL"
cd "$EGGDROP_SRCDIR"
make distclean 2>/dev/null || true
```
### Exporter l’environnement de build
```bash
export CPPFLAGS="-I$TCL_HOME/include -I$OPENSSL_HOME/include"
export LDFLAGS="-L$TCL_HOME/lib -L$OPENSSL_HOME/lib64 -L$OPENSSL_HOME/lib -Wl,-rpath,$TCL_HOME/lib -Wl,-rpath,$OPENSSL_HOME/lib64 -Wl,-rpath,$OPENSSL_HOME/lib"
export LIBS="-lssl -lcrypto -lz -lpthread -lm -lresolv"
export LD_LIBRARY_PATH="$OPENSSL_HOME/lib64:$OPENSSL_HOME/lib:$TCL_HOME/lib"
export PKG_CONFIG_PATH="$OPENSSL_HOME/lib64/pkgconfig:$OPENSSL_HOME/lib/pkgconfig"
```
### Configurer, compiler et installer
```bash
./configure \
--prefix=/opt/eggdrop-lab/eggdrop1101 \
--with-tcllib="$TCL_HOME/lib" \
--with-tclinc="$TCL_HOME/include"
make config
make -j"$(nproc)"
make install DEST="$BOT_HOME/$BOT_INSTANCE"
```
---
## Vérifier le binaire installé
```bash
find "$BOT_HOME/$BOT_INSTANCE" -maxdepth 2 -type f -name 'eggdrop*' -ls
file "$BOT_HOME/$BOT_INSTANCE/eggdrop-1.10.1"
ldd "$BOT_HOME/$BOT_INSTANCE/eggdrop-1.10.1"
```
Le fichier `eggdrop-1.10.1` doit être un vrai **binaire ELF**, pas un script.
Les dépendances doivent pointer vers :
- `"$TCL_HOME/lib/libtcl9.0.so"`
- `"$OPENSSL_HOME/lib64/libssl.so.3"`
- `"$OPENSSL_HOME/lib64/libcrypto.so.3"`
### Vérifier aussi les modules
```bash
ldd "$BOT_HOME/$BOT_INSTANCE/modules-1.10.1/assoc.so"
ldd "$BOT_HOME/$BOT_INSTANCE/modules-1.10.1/blowfish.so"
ldd "$BOT_HOME/$BOT_INSTANCE/modules-1.10.1/server.so"
```
---
## Supprimer le lien symbolique `eggdrop` avant de créer le lanceur
C’est un piège réel.
L’installation staging peut créer ceci :
```bash
eggdrop -> eggdrop-1.10.1
```
Si vous voulez ensuite créer un **script lanceur nommé `eggdrop`**, il faut **supprimer ce lien symbolique avant**, sinon vous partez vers un comportement ambigu ou récursif.
### Vérification
```bash
ls -l "$BOT_HOME/$BOT_INSTANCE/eggdrop"
```
### Suppression du symlink
```bash
rm -f "$BOT_HOME/$BOT_INSTANCE/eggdrop"
```
---
## Créer le lanceur runtime `eggdrop`
Dans cet exemple, on garde volontairement un style shell simple avec `"$EGGROOT/eggdrop-1.10.1" $*`, pour rester proche d’un usage classique.
```bash
cat > "$BOT_HOME/$BOT_INSTANCE/eggdrop" < ERR: $v"
} else {
puts "$p => OK: $v"
}
}
EOF
```
---
## Tester Eggdrop
Cette fois, on utilise bien le lanceur :
```bash
"$BOT_HOME/$BOT_INSTANCE/eggdrop" -v
```
---
## Préparer une vraie configuration d’instance
Ne lancez pas `eggdrop.conf` tel quel comme configuration finale.
Créez une configuration dédiée :
```bash
cp "$BOT_HOME/$BOT_INSTANCE/eggdrop.conf" \
"$BOT_HOME/$BOT_INSTANCE/${BOT_INSTANCE}.conf"
```
Éditez ensuite :
```bash
$BOT_HOME/$BOT_INSTANCE/${BOT_INSTANCE}.conf
```
---
## Initialiser le bot
```bash
"$BOT_HOME/$BOT_INSTANCE/eggdrop" -m "${BOT_INSTANCE}.conf"
```
Puis créez l’owner et définissez le mot de passe.
---
## Lancer en foreground
```bash
"$BOT_HOME/$BOT_INSTANCE/eggdrop" -n "${BOT_INSTANCE}.conf"
```
---
## Pièges importants à retenir
Voici les erreurs les plus faciles à éviter :
1. **Utiliser `tar xzf` pour les archives `.tar.gz`**
2. **Ne pas utiliser de wildcard ambigu comme `cd tcltls-*`**
3. **Pour Tcllib, utiliser `make install-tcl` afin d’éviter une erreur optionnelle liée à Critcl/TcllibC**
4. **Supprimer toute ancienne instance staging avant réinstallation**
5. **Supprimer le lien symbolique `eggdrop -> eggdrop-1.10.1` avant de créer votre propre lanceur `eggdrop`**
6. **Tester Tcl/TclTLS/Tcllib directement avec `tclsh`, pas via le lanceur Eggdrop**
7. **Compiler Eggdrop sous un utilisateur non privilégié**
8. **Choisir soigneusement `BOT_USER`, surtout si identd peut entrer en jeu**
---
## Conclusion
Avec cette approche, vous obtenez une pile Eggdrop moderne, propre et maîtrisée :
- OpenSSL privé
- Tcl privé
- TclTLS privé
- Tcllib privée
- Eggdrop compilé proprement
- runtime isolé
- moins d’ambiguïtés pour le diagnostic de vieux scripts Tcl
Et c’est précisément ce qui rend cette méthode intéressante si vous voulez remettre en route ou moderniser des scripts Tcl historiques sous Eggdrop, sans vous battre en permanence contre les bibliothèques système ou un environnement runtime flou.
---
## Notes finales
Cette procédure a été élaborée à partir d’un vrai travail de validation sur Debian, avec des ajustements concrets à partir des problèmes rencontrés en route.
Elle constitue une bonne base pour :
- un labo propre
- une migration progressive
- ou la préparation d’un article plus large autour de Tcl 9, Eggdrop 1.10.1 et de la compatibilité des scripts historiques