Utiliser Git à travers SSH sous GNU/Linux

On ne présente plus Git, le système distribué de contrôle de version pour gérer les projets de façon efficace, une alternative (par exemple) à SVN se voulant plus souple et plus performante.

Ayant eu à faire la manipulation pour créer un dépôt sur mon serveur domestique et le rendre accessible via SSH avec une paire de clés (publique et privée), je trouve intéressant d’en parler.

Bien que les explications ne manquent pas concernant les étapes de la démarche (Git étant bien documenté en soi), je vous propose une explication détaillée pour achever tout ceci d’un bout à l’autre.

On verra ainsi comment créer un utilisateur “git” sur le serveur, dont le rôle se limitera à exécuter des commandes Git, puis comment créer un premier dépot Git, que l’utilisateur susnommé sera seul à pouvoir manipuler, enfin nous limiterons l’accès à ce compte utilisateur en SSH avec l’utilisation de couples de clés publiques et privées, voilà pourquoi il faudra générer un couple de clés publique/privée.

Création d’un utilisateur “git”.

Cette étape n’est, en elle même, pas spécifique à l’utilisation de git (ni même compliquée en fait), mais elle reste nécessaire et c’est bien de la détailler pour quiconque faisant pour la première fois ce genre de manipulation.

Tout d’abord, on va créer notre utilisateur sur le serveur avec useradd <user>, on se donne les privilèges root (avec su ou en utilisant sudo) puis dans le terminal:
# useradd git

À ce stade là, notre utilisateur git existe sur le système et sans fournir plus d’option que ça à la commande useradd, son dossier par défaut est /home/git, ça tombe bien c’est ce qu’on voulait mais il reste à créer ce dossier, rien de bien compliqué: un mkdir suffit.
# mkdir /home/git

Maintenant il faut que ce dossier appartienne à notre utilisateur git et qu’il ait les droits en lecture et écriture dessus, on va respectivement utiliser chown et chmod:
# chown git:users /home/git
# chmod 755 /home/git

Là on vient de donner la propriété du dossier /home/git à l’utilisateur git et au groupe users qui désigne le groupe par défaut dans lequel un utilisateur se trouve à sa création, à défaut que celui-ci existe faites chown git:git /home/git et le dossier appartiendra au groupe “git” qui s’est créé en même temps que l’utilisateur).

On a également donné les droits en lecture/écriture/exécution à git sur son dossier, les membres du même groupe et les autres n’ont qu’un droit en lecture et exécution.

Là l’utilisateur est bien en place, on va pouvoir s’occuper de la création d’un premier projet Git !

Création d’un projet Git.

Avant toute chose, procurez-vous git pour votre distribution (bah oui !), dans le cas de Debian et ses dérivée (Mint, Ubuntu…) un apt-get install git avec les privilèges root devrait faire l’affaire, utilisant pour ma part Archlinux, un pacman -S git a fait le travail.

On va ensuite décider d’un dossier où placer tous les projets git, on va partir sur l’exemple de /opt/git, qu’il faut donc créer dans opt/.

Pour cela (toujours en root):
# mkdir /opt/git
# chown git:git /opt/git
# chmod 755 /opt/git

En ayant fait l’étape d’avant on comprend ce que ces lignes font: créer un dossier git/ dans opt/ puis on octroie le dossier à l’utilisateur git et à lui uniquement (d’où le fait qu’on donne aussi git en nom de groupe à chmod), puis on définit les droits en lecteur/écriture/exécution pour que l’utilisateur puisse faire ce dont il a besoin dedans.

Il est temps de créer le projet, pour cela:
# su git
$ mkdir /opt/git/projet.git
$ cd /opt/git/projet.git
$ git init --bare

On passe d’abord en utilisateur git avec su (on ne peut d’ailleurs pas le faire autrement puisqu’il n’a pas de mot de passe associé), on créer un dossier destiné à contenir notre premier projet dans /opt/git, on va dedans puis on initialise le projet.

A ce stade le plus gros est fait pour Git, l’idée est maintenant de sécuriser et restreindre l’accès au dépôt qu’à certains utilisateurs auxquels on fait confiance, c’est à dire ceux pour qui le compte git sur le serveur possède la clé publique.

Cette clé servira à déchiffrer ce qu’un utilisateur donné a chiffré avec sa clé privée, SSH se servira des clés de lui-même, pourvu qu’elles soient aux bons endroits et qu’on les ait générées avant, c’est ce que nous allons faire !

 

Générer un couple de clés publique/privée.

C’est assez simple, du coté de votre <>machine client<> (et non pas le serveur), tapez ceci dans un terminal en tant qu’utilisateur (pas en tant que root):
$ ssh-keygen

l’utilisation de la commande ssh-keygen sans fournir d’argument génère deux fichiers dans le dossier .ssh/ de votre répertoire home: id_rsa et id_rsa.pub, le premier contient votre clé privée et le second votre clé publique (d’où le .pub).

Le “rsa” présent dans les noms des fichiers désigne la méthode de chiffrement asymétrique utilisée, par défaut ssh-keygen utilise rsa, mais d’autres sont disponibles, comme ecdsa ou dsa, pour s’en servir il faut utiliser l’option -t de ssh-keygen:
$ ssh-keygen -t ecdsa

Les deux fichiers générés seront alors id_ecdsa et id_ecdsa.pub.

Il est aussi possible de choisir la longueur des clés en nombre de bits grâce à l’option -b, le type de chiffrement conditionne les longueurs possibles utilisables (voir le man de ssh-keygen) pour l’option -b), exemple:
$ ssh-keygen -t ecdsa -b 521

Notez que certaines méthodes de chiffrement sont plus robustes que d’autres, notamment ecdsa par rapport à rsa, retenez aussi qu’au plus la clé est longue, au plus le chiffrement sera difficile (et long) à casser, par exemple si vous voulez utiliser rsa, la longueur par défaut est de 2048 bits, il est possible d’augmenter ce nombre (voire de le doubler) toujours avec l’option -b.

Importer sa clé publique sur le serveur.

Bon, à ce stade le compte git sur le serveur est créé, un premier dépôt a été initialisé, et vous avez votre couple clé publique/privé.

Maintenant il va falloir que vous puissiez utiliser git au travers de ssh sur le serveur, pour cela il faut que l’utilisateur git sur le server ait votre clé publique.

Coté client: récupérez le contenu de votre fichier id_ecdsa.pub (ou id_rsa.pub, selon la méthode que vous avez utilisé) par exemple, en le faisant de mon coté:
$ cat ~/.ssh/id_ecdsa.pub
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADysewrcaOUZl2wHNssiCwO2a6msDZ4FIOgjv9Hh5M1GQKcHQ3SiqJJWdOklnZ8Y7Jp65gF7gR/RL1qfvaQWSgZZgA58VBgZk9g8PMyok13Pn2i6ye9gQR94R1n/h7HyDHZXkpj91RskPE52u2qSZv3SDTZLOOeC4V/xCpj/f9ONf3usQ== blax@blax-arch

Là vous pouvez voir le contenu de mon fichier id_ecdsa.pub, la clé publique est (comme son nom le suggère) faite pour être connue des autres, à l’opposé de la clé privée que vous ne devez jamais divulguer.

On voit une longue ligne avec en premier le type de chiffrement utilisé, suivi de la clé en question (sa longueur dépend de ce que vous avez choisi de faire avec ssh-keygen), puis à la fin un commentaire (qui n’aura aucune incidence sur ce que SSH fera) qui indique mon nom d’utilisateur et le nom de ma machine, c’est complètement facultatif mais il est de mauvais aloi de le supprimer: c’est ce commentaire qui vous permettra par la suite de distinguer les clés les unes des autres (dans l’optique où vous en ajouteriez plusieurs).

il suffit ensuite simplement de… “copier-coller” ceci dans le fichier authorized_keys du dossier .ssh/ de l’utilisateur git sur le serveur.
Normalement ce fichier en question n’existe par encore, ni le dossier .ssh/, pas de problème, on peut les créer, comme les fois d’avant loguez vous sur le serveur avec votre compte utilisateur, passez en root puis faites:
# su git
$ mkdir ~/.ssh
$ touch ~/.ssh/authorized_keys
$ vi ~/.ssh/authorized_keys

le fichier a été créé, puis ouvert avec vi (ou vim, ou nano, comme vous voulez), insérer le contenu de votre id_ecdsa.pub à l’intérieur, puis sauvegardez.

Vous pouvez vérifier que ça s’est bien passé:
$ cat /home/git/.ssh/authorized_keys
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADysewrcaOUZl2wHNssiCwO2a6msDZ4FIOgjv9Hh5M1GQKcHQ3SiqJJWdOklnZ8Y7Jp65gF7gR/RL1qfvaQWSgZZgA58VBgZk9g8PMyok13Pn2i6ye9gQR94R1n/h7HyDHZXkpj91RskPE52u2qSZv3SDTZLOOeC4V/xCpj/f9ONf3usQ== blax@blax-arch

Le contenu du fichier devrait être le même sur celui de votre <em>id_ecdsa.pub</em> coté machine client.

Normalement à ce stade là tout devrait être bon MAIS (car il y a un mais) selon la configuration de sshd sur votre serveur, il se peut que votre utilisateur git n’ait pas le droit de se loguer en ssh.

Pour vérifier cela, contrôlez le contenu de /etc/ssh/sshd_config (en étant root sur le serveur), si la ligne AllowUsers est présente, cela veut dire que seuls les utilisateurs indiqués dans la directive ont le droit de se loguer en ssh sur la machine, ajoutez donc git à la liste des utilisateurs, ce qui devrait donner quelque chose du genre:
AllowUsers blax git

Il me semble de bon ton de le préciser, puisque ça n’était pas indiqué dans la procédure que j’ai moi-même suivi pour configurer mon dépôt Git pour la première fois, j’ai donc perdu un certain temps là dessus, mais ça dépend de la configuration par défaut de sshd d’une distribution à l’autre.

Utiliser (enfin) le dépôt Git.

Ça y est, vous pouvez profiter de votre dépôt Git !

Sur votre machine client, avec votre compte utilisateur, essayez de cloner le dépôt:
$ git clone ssh://git@monserveur/opt/git/projet.git

Si tout s’est bien passé, déjà il ne vous sera pas demandé de mot de passe, vous êtes sensé être authentifié à l’aide de votre clé privée (et pourvu que le serveur ait votre clé publique), si un mot de passe vous est demandé, revoyez l’étape concernant la génération de clé (et l’importation sur le serveur).

Au delà de la partie authentification, le dépôt devrait se cloner sans encombre coté client si il a été créé comme il faut coté serveur, sinon revoyez le début du tutoriel.

Un bond dans le passé, Microsoft Office style !

Je ne m’intéresse pas plus que ça au Javacript et ne fais pas spécialement de veille concernant la dernière librairie en vogue pour faire de jolis trucs qui bougent, pour autant je suis tombé sur un projet plus qu’insolite et à la fois marrant !

Parlons d’un temps que les moins de vingt ans ne peuvent pas connaître, celui de Microsoft Office 97 et 2003… bon c’est pas si lointain que ça (quoi que), mais le fait est qu’à ce moment là en même temps qu’on ouvrait Word, on avait un petit assistant animé nommé Clippy en surcouche dans le logiciel.

Clippy Microsoft

Clippy le trombone, fallait le pondre lui quand même!

Grosso modo: c’était supposé nous donner des conseils de temps et temps pendant l’utilisation du fameux traitement de texte.

Bien qu’en pratique d’une utilité et d’un intérêt encore incertain (il était connu pour ça d’ailleurs), après plusieurs années et même après sa disparition, c’est devenu une sorte de “figure emblématique” de la culture informatique, presque érigée au rang de meme en partie pour moquer Microsoft.

Le lien avec le Javascript ? Et bien il existe une librairie permettant d’insérer Clippy sur son site web, j’ai nommé Clippy.js.

La “librairie” en question ne se veut pas révolutionnaire ou techniquement poussée, d’ailleurs c’est clairement dit sur le site que ça n’a mis qu’un week-end à se faire suite à une idée lancée lors d’un déjeuner entre les développeurs, mais tout de même: il ont pris le temps de le faire !

On retrouve aussi les autres “mascottes” comme Rover, Merlin ou Links, qui sont en fait des habillages alternatifs de l’assistant que l’on pouvait choisir si Clippy ne convenait pas.

Bon par contre, comptez pas sur moi pour foutre ça ici hein.

Left 4 Dead 2, enfin sur Steam pour Linux

Left 4 Dead 2 est enfin disponible (en Beta pour l’instant) pour les utilisateurs de Steam sous GNU/Linux !

Left 4 Dead 2

C’est une bonne chose de faite, mais curieusement c’est loin d’être le premier jeu Source (Half-Life, Day of Defeat, Counter Strike…) a avoir été porté et rendu accessible, alors que c’est pourtant le premier jeu sur lequel Valve communiquait à propos du portage de Steam.

Pour rappel: le portage de L4D2 s’est fait en collaboration avec NVidia, AMD et Intel, même il y a quelques mois de ça les performances étaient déjà au rendez-vous.

La raison à ce délai est sûrement légitime: l’intérêt de se focaliser dès le départ sur ce jeu (plutôt qu’un autre) vient probablement du nombre de détails et de points techniques gênants à régler pour que le portage soit viable. Traiter un cas “pathologique” en premier permet de gérer plus facilement les cas plus simples par la suite, ce qui doit expliquer la rapidité avec laquelle d’autres jeux Source ont été rendus compatibles, les efforts fournis sur Left 4 Dead 2 y étant sûrement pour quelque chose.

De mon coté le jeu est entrain de télécharger, je vais faire de même pour Portal (1er du nom) disponible depuis cette semaine également.

OpenCV et CMake sous OSX 10.5

Halte là, pas de fausse joie: en dépit du titre, je ne cautionne pas spécialement le développement logiciel dans un environnement Mac OSX, il y a assez de distributions GNU/Linux pour ça.

Mais si vous avez un grain ou que vous êtes contraints de bosser sous OSX sur votre lieu de travail (j’obéis au second cas), il se peut que vous ayez des problèmes avec CMake, enfin plutôt avec certains modules auxquels vous ferez appel.

Là on va surtout parler d’OpenCV, la fameuse libraire pour le traitement et l’analyse d’image en C++ installée par le biais de macports, l’initiative opensource pour donner à OSX un gestionnaire de paquets (et de dépendances) un peu à la apt-get/yum/pacman etc…

Si en général tout s’installe bien et proprement, quelques détails passent pourtant à la trappe, notamment la mise à disposition d’un fichier fonctionnel pour trouver le module OpenCV avec CMake: FindOpenCV.cmake (respectant la nomenclature FindNomDuModule.cmake).

Considérons que dans notre projet nous avons un dossier cmake-modules/ au même niveau que CMakeLists.txt, dans ce dossier se trouvent tous nos FindMachinTruc.cmake, pour trouver les modules nécessaires à la compilation et au linkage du programme.

Prenons les lignes suivantes du dit CMakeLists.txt:


PROJECT( mon-projet ) # le nom du projet, ouais !!
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules) # J'inclue un nouveau répertoire dans lequel regarder pour trouver tous mes modules, c'est notre cmake-modules/.
FIND_PACKAGE( OpenCV REQUIRED ) # Ici, je cherche OpenCV.

Si vous voulez le foutu de FindOpenCV.cmake à placer dans votre cmake-modules/, le voici:

# ===================================================================================
#  The OpenCV CMake configuration file
#
#             ** File generated automatically, do not modify **
#
#  Usage from an external project:
#    In your CMakeLists.txt, add these lines:
#
#    FIND_PACKAGE(OpenCV REQUIRED)
#    TARGET_LINK_LIBRARIES(MY_TARGET_NAME ${OpenCV_LIBS})
#
#    Or you can search for specific OpenCV modules:
#
#    FIND_PACKAGE(OpenCV REQUIRED core highgui)
#
#    If the module is found then OPENCV_<MODULE>_FOUND is set to TRUE.
#
#    This file will define the following variables:
#      - OpenCV_LIBS                     : The list of libraries to links against.
#      - OpenCV_LIB_DIR                  : The directory(es) where lib files are. Calling LINK_DIRECTORIES
#                                          with this path is NOT needed.
#      - OpenCV_INCLUDE_DIRS             : The OpenCV include directories.
#      - OpenCV_COMPUTE_CAPABILITIES     : The version of compute capability
#      - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API
#      - OpenCV_VERSION                  : The version of this OpenCV build. Example: "2.4.3"
#      - OpenCV_VERSION_MAJOR            : Major version part of OpenCV_VERSION. Example: "2"
#      - OpenCV_VERSION_MINOR            : Minor version part of OpenCV_VERSION. Example: "4"
#      - OpenCV_VERSION_PATCH            : Patch version part of OpenCV_VERSION. Example: "3"
#
#    Advanced variables:
#      - OpenCV_SHARED
#      - OpenCV_CONFIG_PATH
#      - OpenCV_INSTALL_PATH  (not set on Windows)
#      - OpenCV_LIB_COMPONENTS
#      - OpenCV_USE_MANGLED_PATHS
#      - OpenCV_HAVE_ANDROID_CAMERA
#
# ===================================================================================

# Version Compute Capability from which OpenCV has been compiled is remembered
set(OpenCV_COMPUTE_CAPABILITIES "")

set(OpenCV_CUDA_VERSION )
set(OpenCV_USE_CUBLAS )
set(OpenCV_USE_CUFFT  )

# Android API level from which OpenCV has been compiled is remembered
set(OpenCV_ANDROID_NATIVE_API_LEVEL 0)

# Some additional settings are required if OpenCV is built as static libs
set(OpenCV_SHARED ON)

# Enables mangled install paths, that help with side by side installs
set(OpenCV_USE_MANGLED_PATHS FALSE)

# Extract the directory where *this* file has been installed (determined at cmake run-time)
# get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE)

# EXEC_PROGRAM(locate OpenCVConfig.cmake
#                OUTPUT_VARIABLE OpenCV_TMP_CONFIG_PATH)

set(OpenCV_CONFIG_PATH /opt/local/lib/cmake)

if(NOT WIN32 OR OpenCV_ANDROID_NATIVE_API_LEVEL GREATER 0)
if(OpenCV_ANDROID_NATIVE_API_LEVEL GREATER 0)
set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../../..")
else()
set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../..")
endif()
# Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" ABSOLUTE)
else()
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" REALPATH)
endif()
endif()

# Presence of Android native camera wrappers
set(OpenCV_HAVE_ANDROID_CAMERA OFF)

# ======================================================
# Include directories to add to the user project:
# ======================================================

# Provide the include directories to the caller
set(OpenCV_INCLUDE_DIRS "${OpenCV_INSTALL_PATH}/include/opencv;${OpenCV_INSTALL_PATH}/include")
include_directories(${OpenCV_INCLUDE_DIRS})

# ======================================================
# Link directories to add to the user project:
# ======================================================

# Provide the libs directories to the caller
set(OpenCV_LIB_DIR_OPT "${OpenCV_INSTALL_PATH}/lib" CACHE PATH "Path where release OpenCV libraries are located")
set(OpenCV_LIB_DIR_DBG "${OpenCV_INSTALL_PATH}/lib" CACHE PATH "Path where debug OpenCV libraries are located")
set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_INSTALL_PATH}/share/OpenCV/3rdparty/lib" CACHE PATH "Path where release 3rdpaty OpenCV dependencies are located")
set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_INSTALL_PATH}/share/OpenCV/3rdparty/lib" CACHE PATH "Path where debug 3rdpaty OpenCV dependencies are located")
mark_as_advanced(FORCE OpenCV_LIB_DIR_OPT OpenCV_LIB_DIR_DBG OpenCV_3RDPARTY_LIB_DIR_OPT OpenCV_3RDPARTY_LIB_DIR_DBG OpenCV_CONFIG_PATH)

# ======================================================
#  Version variables:
# ======================================================
SET(OpenCV_VERSION 2.4.3)
SET(OpenCV_VERSION_MAJOR  2)
SET(OpenCV_VERSION_MINOR  4)
SET(OpenCV_VERSION_PATCH  3)

# ====================================================================
# Link libraries: e.g.   libopencv_core.so, opencv_imgproc220d.lib, etc...
# ====================================================================

SET(OpenCV_LIB_COMPONENTS opencv_videostab;opencv_video;opencv_ts;opencv_stitching;opencv_photo;opencv_objdetect;opencv_nonfree;opencv_ml;opencv_legacy;opencv_imgproc;opencv_highgui;opencv_gpu;opencv_flann;opencv_features2d;opencv_core;opencv_contrib;opencv_calib3d)

set(OpenCV_opencv_videostab_LIBNAME_OPT "libopencv_videostab.dylib")
set(OpenCV_opencv_videostab_DEPS_OPT )
set(OpenCV_opencv_videostab_EXTRA_DEPS_OPT )
set(OpenCV_opencv_video_LIBNAME_OPT "libopencv_video.dylib")
set(OpenCV_opencv_video_DEPS_OPT )
set(OpenCV_opencv_video_EXTRA_DEPS_OPT )
set(OpenCV_opencv_ts_LIBNAME_OPT "libopencv_ts.dylib")
set(OpenCV_opencv_ts_DEPS_OPT )
set(OpenCV_opencv_ts_EXTRA_DEPS_OPT )
set(OpenCV_opencv_stitching_LIBNAME_OPT "libopencv_stitching.dylib")
set(OpenCV_opencv_stitching_DEPS_OPT )
set(OpenCV_opencv_stitching_EXTRA_DEPS_OPT )
set(OpenCV_opencv_photo_LIBNAME_OPT "libopencv_photo.dylib")
set(OpenCV_opencv_photo_DEPS_OPT )
set(OpenCV_opencv_photo_EXTRA_DEPS_OPT )
set(OpenCV_opencv_objdetect_LIBNAME_OPT "libopencv_objdetect.dylib")
set(OpenCV_opencv_objdetect_DEPS_OPT )
set(OpenCV_opencv_objdetect_EXTRA_DEPS_OPT )
set(OpenCV_opencv_nonfree_LIBNAME_OPT "libopencv_nonfree.dylib")
set(OpenCV_opencv_nonfree_DEPS_OPT )
set(OpenCV_opencv_nonfree_EXTRA_DEPS_OPT )
set(OpenCV_opencv_ml_LIBNAME_OPT "libopencv_ml.dylib")
set(OpenCV_opencv_ml_DEPS_OPT )
set(OpenCV_opencv_ml_EXTRA_DEPS_OPT )
set(OpenCV_opencv_legacy_LIBNAME_OPT "libopencv_legacy.dylib")
set(OpenCV_opencv_legacy_DEPS_OPT )
set(OpenCV_opencv_legacy_EXTRA_DEPS_OPT )
set(OpenCV_opencv_imgproc_LIBNAME_OPT "libopencv_imgproc.dylib")
set(OpenCV_opencv_imgproc_DEPS_OPT )
set(OpenCV_opencv_imgproc_EXTRA_DEPS_OPT )
set(OpenCV_opencv_highgui_LIBNAME_OPT "libopencv_highgui.dylib")
set(OpenCV_opencv_highgui_DEPS_OPT )
set(OpenCV_opencv_highgui_EXTRA_DEPS_OPT )
set(OpenCV_opencv_gpu_LIBNAME_OPT "libopencv_gpu.dylib")
set(OpenCV_opencv_gpu_DEPS_OPT )
set(OpenCV_opencv_gpu_EXTRA_DEPS_OPT )
set(OpenCV_opencv_flann_LIBNAME_OPT "libopencv_flann.dylib")
set(OpenCV_opencv_flann_DEPS_OPT )
set(OpenCV_opencv_flann_EXTRA_DEPS_OPT )
set(OpenCV_opencv_features2d_LIBNAME_OPT "libopencv_features2d.dylib")
set(OpenCV_opencv_features2d_DEPS_OPT )
set(OpenCV_opencv_features2d_EXTRA_DEPS_OPT )
set(OpenCV_opencv_core_LIBNAME_OPT "libopencv_core.dylib")
set(OpenCV_opencv_core_DEPS_OPT )
set(OpenCV_opencv_core_EXTRA_DEPS_OPT )
set(OpenCV_opencv_contrib_LIBNAME_OPT "libopencv_contrib.dylib")
set(OpenCV_opencv_contrib_DEPS_OPT )
set(OpenCV_opencv_contrib_EXTRA_DEPS_OPT )
set(OpenCV_opencv_calib3d_LIBNAME_OPT "libopencv_calib3d.dylib")
set(OpenCV_opencv_calib3d_DEPS_OPT )
set(OpenCV_opencv_calib3d_EXTRA_DEPS_OPT )

set(OpenCV_opencv_videostab_LIBNAME_DBG "libopencv_videostab.dylib")
set(OpenCV_opencv_videostab_DEPS_DBG )
set(OpenCV_opencv_videostab_EXTRA_DEPS_DBG )
set(OpenCV_opencv_video_LIBNAME_DBG "libopencv_video.dylib")
set(OpenCV_opencv_video_DEPS_DBG )
set(OpenCV_opencv_video_EXTRA_DEPS_DBG )
set(OpenCV_opencv_ts_LIBNAME_DBG "libopencv_ts.dylib")
set(OpenCV_opencv_ts_DEPS_DBG )
set(OpenCV_opencv_ts_EXTRA_DEPS_DBG )
set(OpenCV_opencv_stitching_LIBNAME_DBG "libopencv_stitching.dylib")
set(OpenCV_opencv_stitching_DEPS_DBG )
set(OpenCV_opencv_stitching_EXTRA_DEPS_DBG )
set(OpenCV_opencv_photo_LIBNAME_DBG "libopencv_photo.dylib")
set(OpenCV_opencv_photo_DEPS_DBG )
set(OpenCV_opencv_photo_EXTRA_DEPS_DBG )
set(OpenCV_opencv_objdetect_LIBNAME_DBG "libopencv_objdetect.dylib")
set(OpenCV_opencv_objdetect_DEPS_DBG )
set(OpenCV_opencv_objdetect_EXTRA_DEPS_DBG )
set(OpenCV_opencv_nonfree_LIBNAME_DBG "libopencv_nonfree.dylib")
set(OpenCV_opencv_nonfree_DEPS_DBG )
set(OpenCV_opencv_nonfree_EXTRA_DEPS_DBG )
set(OpenCV_opencv_ml_LIBNAME_DBG "libopencv_ml.dylib")
set(OpenCV_opencv_ml_DEPS_DBG )
set(OpenCV_opencv_ml_EXTRA_DEPS_DBG )
set(OpenCV_opencv_legacy_LIBNAME_DBG "libopencv_legacy.dylib")
set(OpenCV_opencv_legacy_DEPS_DBG )
set(OpenCV_opencv_legacy_EXTRA_DEPS_DBG )
set(OpenCV_opencv_imgproc_LIBNAME_DBG "libopencv_imgproc.dylib")
set(OpenCV_opencv_imgproc_DEPS_DBG )
set(OpenCV_opencv_imgproc_EXTRA_DEPS_DBG )
set(OpenCV_opencv_highgui_LIBNAME_DBG "libopencv_highgui.dylib")
set(OpenCV_opencv_highgui_DEPS_DBG )
set(OpenCV_opencv_highgui_EXTRA_DEPS_DBG )
set(OpenCV_opencv_gpu_LIBNAME_DBG "libopencv_gpu.dylib")
set(OpenCV_opencv_gpu_DEPS_DBG )
set(OpenCV_opencv_gpu_EXTRA_DEPS_DBG )
set(OpenCV_opencv_flann_LIBNAME_DBG "libopencv_flann.dylib")
set(OpenCV_opencv_flann_DEPS_DBG )
set(OpenCV_opencv_flann_EXTRA_DEPS_DBG )
set(OpenCV_opencv_features2d_LIBNAME_DBG "libopencv_features2d.dylib")
set(OpenCV_opencv_features2d_DEPS_DBG )
set(OpenCV_opencv_features2d_EXTRA_DEPS_DBG )
set(OpenCV_opencv_core_LIBNAME_DBG "libopencv_core.dylib")
set(OpenCV_opencv_core_DEPS_DBG )
set(OpenCV_opencv_core_EXTRA_DEPS_DBG )
set(OpenCV_opencv_contrib_LIBNAME_DBG "libopencv_contrib.dylib")
set(OpenCV_opencv_contrib_DEPS_DBG )
set(OpenCV_opencv_contrib_EXTRA_DEPS_DBG )
set(OpenCV_opencv_calib3d_LIBNAME_DBG "libopencv_calib3d.dylib")
set(OpenCV_opencv_calib3d_DEPS_DBG )
set(OpenCV_opencv_calib3d_EXTRA_DEPS_DBG )

# ==============================================================
#  Extra include directories, needed by OpenCV 2 new structure
# ==============================================================
SET(OpenCV2_INCLUDE_DIRS "")
if(OpenCV2_INCLUDE_DIRS)
include_directories(${OpenCV2_INCLUDE_DIRS})
list(APPEND OpenCV_INCLUDE_DIRS ${OpenCV2_INCLUDE_DIRS})

set(OpenCV_ADD_DEBUG_RELEASE FALSE)
if(OpenCV_ADD_DEBUG_RELEASE)
set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_DIR_OPT}/Release")
set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_DIR_DBG}/Debug")
set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_3RDPARTY_LIB_DIR_OPT}/Release")
set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_3RDPARTY_LIB_DIR_DBG}/Debug")
endif()
endif()

# ==============================================================
#  Check OpenCV availability
# ==============================================================
if(ANDROID AND OpenCV_ANDROID_NATIVE_API_LEVEL GREATER ANDROID_NATIVE_API_LEVEL)
message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}")
#always FATAL_ERROR because we can't say to the caller that OpenCV is not found
#http://www.mail-archive.com/cmake@cmake.org/msg37831.html
if(OpenCV_FIND_REQUIRED)
message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}")
elseif(NOT OpenCV_FIND_QUIETLY)
message(WARNING "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}")
endif()
set(OpenCV_FOUND "OpenCV_FOUND-NOTFOUND")
return()#Android toolchain requires CMake > 2.6
endif()

# ==============================================================
#  Form list of modules (components) to find
# ==============================================================
if(NOT OpenCV_FIND_COMPONENTS)
set(OpenCV_FIND_COMPONENTS ${OpenCV_LIB_COMPONENTS})
if(GTest_FOUND OR GTEST_FOUND)
list(REMOVE_ITEM OpenCV_FIND_COMPONENTS opencv_ts)
endif()
endif()

# expand short module names and see if requested components exist
set(OpenCV_FIND_COMPONENTS_ "")
foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS})
if(NOT __cvcomponent MATCHES "^opencv_")
set(__cvcomponent opencv_${__cvcomponent})
endif()
list(FIND OpenCV_LIB_COMPONENTS ${__cvcomponent} __cvcomponentIdx)
if(__cvcomponentIdx LESS 0)
#requested component is not found...
if(OpenCV_FIND_REQUIRED)
message(FATAL_ERROR "${__cvcomponent} is required but was not found")
elseif(NOT OpenCV_FIND_QUIETLY)
message(WARNING "${__cvcomponent} is required but was not found")
endif()
#indicate that module is NOT found
string(TOUPPER "${__cvcomponent}" __cvcomponent)
set(${__cvcomponent}_FOUND "${__cvcomponent}_FOUND-NOTFOUND")
else()
list(APPEND OpenCV_FIND_COMPONENTS_ ${__cvcomponent})
#indicate that module is found
string(TOUPPER "${__cvcomponent}" __cvcomponent)
set(${__cvcomponent}_FOUND 1)
endif()
endforeach()
set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_})

# ==============================================================
#  Resolve dependencies
# ==============================================================
if(OpenCV_USE_MANGLED_PATHS)
set(OpenCV_LIB_SUFFIX ".${OpenCV_VERSION}")
else()
set(OpenCV_LIB_SUFFIX "")
endif()

foreach(__opttype OPT DBG)
SET(OpenCV_LIBS_${__opttype} "")
SET(OpenCV_EXTRA_LIBS_${__opttype} "")
foreach(__cvlib ${OpenCV_FIND_COMPONENTS})
foreach(__cvdep ${OpenCV_${__cvlib}_DEPS_${__opttype}})
if(__cvdep MATCHES "^opencv_")
list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}${OpenCV_LIB_SUFFIX}")
#indicate that this module is also found
string(TOUPPER "${__cvdep}" __cvdep)
set(${__cvdep}_FOUND 1)
else()
list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_3RDPARTY_LIB_DIR_${__opttype}}/${OpenCV_${__cvdep}_LIBNAME_${__opttype}}")
endif()
endforeach()
list(APPEND OpenCV_LIBS_${__opttype} "${OpenCV_LIB_DIR_${__opttype}}/${OpenCV_${__cvlib}_LIBNAME_${__opttype}}${OpenCV_LIB_SUFFIX}")
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${OpenCV_${__cvlib}_EXTRA_DEPS_${__opttype}})
endforeach()

if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 2.4)
if(OpenCV_LIBS_${__opttype})
list(REMOVE_DUPLICATES OpenCV_LIBS_${__opttype})
endif()
if(OpenCV_EXTRA_LIBS_${__opttype})
list(REMOVE_DUPLICATES OpenCV_EXTRA_LIBS_${__opttype})
endif()
else()
#TODO: duplicates are annoying but they should not be the problem
endif()
# fix hard coded paths for CUDA libraries under Windows
if(WIN32 AND OpenCV_CUDA_VERSION AND NOT OpenCV_SHARED)
if(NOT CUDA_FOUND)
find_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED)
else()
if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION)
message(FATAL_ERROR "OpenCV static library compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}")
endif()
endif()

list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY} ${CUDA_nvcuvid_LIBRARY} ${CUDA_nvcuvenc_LIBRARY})

if(OpenCV_USE_CUBLAS)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUBLAS_LIBRARIES})
endif()

if(OpenCV_USE_CUFFT)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUFFT_LIBRARIES})
endif()

endif()
endforeach()

if(OpenCV_LIBS_DBG)
list(REVERSE OpenCV_LIBS_DBG)
endif()

if(OpenCV_LIBS_OPT)
list(REVERSE OpenCV_LIBS_OPT)
endif()

# CMake>=2.6 supports the notation "debug XXd optimized XX"
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 2.4)
# Modern CMake:
SET(OpenCV_LIBS "")
foreach(__cvlib ${OpenCV_LIBS_DBG} ${OpenCV_EXTRA_LIBS_DBG})
list(APPEND OpenCV_LIBS debug "${__cvlib}")
endforeach()
foreach(__cvlib ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT})
list(APPEND OpenCV_LIBS optimized "${__cvlib}")
endforeach()
else()
# Old CMake:
if(CMAKE_BUILD_TYPE MATCHES "Debug")
SET(OpenCV_LIBS ${OpenCV_LIBS_DBG} ${OpenCV_EXTRA_LIBS_DBG})
else()
SET(OpenCV_LIBS ${OpenCV_LIBS_OPT} ${OpenCV_EXTRA_LIBS_OPT})
endif()
endif()

# ==============================================================
#  Android camera helper macro
# ==============================================================
if(OpenCV_HAVE_ANDROID_CAMERA)
macro(COPY_NATIVE_CAMERA_LIBS target)
get_target_property(target_location ${target} LOCATION)
get_filename_component(target_location "${target_location}" PATH)
file(GLOB camera_wrappers "${OpenCV_LIB_DIR_OPT}/libnative_camera_r*.so")
foreach(wrapper ${camera_wrappers})
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${target_location}"
)
endforeach()
endmacro()
endif()

# ==============================================================
# Compatibility stuff
# ==============================================================
if(CMAKE_BUILD_TYPE MATCHES "Debug")
SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_DBG} ${OpenCV_3RDPARTY_LIB_DIR_DBG})
else()
SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_OPT} ${OpenCV_3RDPARTY_LIB_DIR_OPT})
endif()
set(OpenCV_LIBRARIES ${OpenCV_LIBS})

Celui-ci sous OSX (et ailleurs j’ose l’espérer) permet avec CMake de trouver les entêtes, les librairies et les flags d’OpenCV nécessaires et par extension de compiler-linker votre programme à partir de vos sources et du dossier des modules présent dans le projet, ce qui le rend exportable.

Le BeagleBone Black

J’ai parlé de UDOO il y a plusieurs jours, dans la même veine le BeagleBone de BeagleBoard se présente sous une nouvelle mouture: le BeagleBone Black, disponible pour $45 en mai, ce qui fait de lui un concurrent direct du Raspberry Pi.

BeagleBone Black 2013

Même si la framboise s’obtient pour $35, il faut compter en plus de ça une carte SD (pour booter sur l’OS qui s’y trouve) ainsi que la connectique avec à minima un câble micro USB pour l’alimentation, on dépasse alors les $45 en tout.

Le Bone quant à lui dispose de 2Go de stockage en interne avec Angstrom Linux pré-installé et il reste  possible de booter sur un autre OS grâce au lecteur microSD inclus, un cable d’alimentation est également fourni (un vrai, pas un câble micro USB).

Mais ça ne s’arrête pas là: outre un packaging plus exhaustif pour un prix au final plus intéressant, ce board computer présente de meilleurs spécifications, dont un processeur Sitara ARM Cortex-A8 (de Texas Instrument) cadencé à 1Ghz contre le ARM11 (de Broadcom) sur le Pi à 700Mhz et répondant à une architecture plus vieille. Le Bone supporte plus de systèmes et de distributions du fait de son architecture processeur, dont Ubuntu et Android.

Pour achever la description: le mini PC dispose aussi d’un bouton power, d’un bouton reset, d’un port USB client, d’un port USB Hôte, de 2 broches à 46 pins chacune et de 512 Mo de mémoire RAM (DDR3).

BeagleBone-Black

BeagleBoard a pu obtenir de large volumes de commandes de la part des distributeurs pour le BeagleBone Black, rendant alors possible des économies d’échelle expliquant ce prix bas à l’unité.

On peut donc parier que Raspberry Pi (la fondation) fasse de même et baisse éventuellement le prix, sachant qu’en termes de volumes écoulés et de popularité on est à un tout autre niveau, c’est simplement que rien ne justifiait un prix plus bas auparavant quand le devenir du Pi était encore incertain.

UDOO: un Raspberry Pi en plus musclé

Un nouveau projet de board computer est dans la place !

UDOO est défini par ses créateurs comme un Rapsberry Pi en quatre fois plus puissant, intègrant en plus une Interface Arduino, le tout supportant aussi bien GNU/Linux qu’Android (4.0.4).

UDOO board computer

Un peu comme le Pi, UDOO a les objectifs suivants:

  • Développer un produit innovant pour un marché toujours plus grand.
  • Fournir au monde de l’éducation un nouvel outil de travail, aussi bien pour former les ingénieurs, les développeurs logiciel que les designers.
  • Contribuer au monde du DIY (Do It Yourself, “Faites-le vous-même”).
  • Offrir un support peu coûteux pour plusieurs outils puissants (Processing, OpenCV, PureData, openFramwork)
  • Fournir aux entreprises un outil adapté au prototypage.

Le projet fait en ce moment sa campagne KickStarter (depuis 3 jours) et a déjà récolté bien plus que les $27,000 espérés, autant dire que la petite machine va devenir une réalité surtout qu’il existe déjà un prototype fonctionnel (voir la vidéo).

Les spécifications pour donner une idée de l’engin:

  • Freescale i.MX 6 ARM Cortex-A9 CPU Dua/Quad core 1GHz
  • Integrated graphics, each processor provides 3 separated accelerators for 2D, OpenGL® ES2.0 3D and OpenVG™
  • Atmel SAM3X8E ARM Cortex-M3 CPU (same as Arduino Due)
  • RAM DDR3 1GB
  • 54 Digital I/O + Analog Input (Arduino-compatible R3 1.0 pinout)
  • HDMI and LVDS + Touch (I2C signals)
  • Ethernet RJ45 (10/100/1000 MBit)
  • WiFi Module 
  • Mini USB and Mini USB OTG
  • USB type A (x2) and USB connector (requires a specific wire)
  • Analog Audio and Mic
  • SATA (Only Quad-Core version)
  • Camera connection
  • Micro SD (boot device)
  • Power Supply (5-12V) and External  Battery connector

Apparemment le mini-PC sera disponible en version Dual Core pour $109 et Quad Core pour $129 (avec $15 en plus pour expédier en dehors de Etats-Unis…) le tout d’ici septembre 2013, les prix restent très honnêtes vis à vis des spécifications.

On peut dire que c’est une belle initiative. Sans parler d’originalité, puisque c’est pas le premier produit de ce type qui voit le jour, ça reste device qui satisfera les bidouilleurs ambitieux et investis , notamment grâce à son support Arduino. Les autres pourront se contenter de leur Raspberry Pi ou autre, je pense donc que ça complète le marché des mini-PC sans pour autant faire de l’ombre à tout ce qui existe déjà.

Ouya: une pré-sortie mitigée

La Ouya a fait sa pré-sortie il y a peu.

Ouya console Android

Le premier batch de la petite console de salon indie sous Android 4.1 a été envoyé aux investisseurs (“backers” du projet Kickstarter), de quoi se faire une idée avant sa sortie officielle en juin.

Entre autre, The Verge s’est attelé à une review (mitigée) de la console.

Si le potentiel de la petite boite est indéniable et qu’elle tient en partie ses promesses sur l’aspect customisation et hacking (quoi que non sans mal) il apparaît clairement que la petite console n’est pas prête pour le grand public.
Le site américain témoigne d’une interface incomplète et un peu lente, d’un ensemble de jeux disponibles plutôt réduit, mais surtout (plus génant selon moi) d’un manque de réactivité de la manette, ainsi qu’une sensation pâteuse au niveau des gâchettes.

Ouya (la compagnie du même nom) a répondu à ces critiques en précisant que les modèles expédiés n’était pas prévus pour une review et que l’expérience utilisateur sera au point d’ici la sortie en juin.

Au programme des améliorations, Ouya mentionne:

-Possibilité d’utiliser un support de stockage externe (pour étendre les 8Go de la console).

-Simplification du processus d’installation des jeux.

-Plus d’outils de mesure pour les développeurs.

-Support de la manette par les lecteurs vidéo.

-Plus d’options de payement.

On a envie de dire “y a plus qu’à attendre”, toujours est-il qu’en deux mois ça fait beaucoup de points à rectifier pour la petite boite dont l’ambition est de remettre en cause le marché actuel des consoles de salon (Xbox 360, PS3…).

Quoi qu’il en soit ça reste, je pense, un petit device sympa et pas trop coûteux pour les amateurs de bidouille (je m’en prendrai sûrement une à terme) à défaut de trouver sa place auprès du grand public: m’importe plus le coté hacking et customisation pourvu qu’il soit au rendez-vous !

Un Alienware sous Ubuntu

Oui oui, on parle bien d’un PC conçu pour jeu sous Ubuntu.

Alienware Ubuntu X51

Les machines commercialisées avec le système d’exploitation sud-africain sont des plus en plus nombreuses (sans toutefois constituer une grosse partie du marché).

Ce n’est pas la première machine que Dell sort avec la populaire distribution GNU/Linux disponible et Dell n’est pas non plus le seul à le faire puisque ça s’est aussi vu, par exemple, chez Asus avec les EeePC, ce qui ne date pas d’hier.

Ce petit rappel de fait, là on parle tout de même d’un Alienware, le X51 a un prix d’entrée de $599, ce qui peut aller jusqu’au double selon les options.

Plus que les spécifications techniques (respectables par rapport au prix), ce qui est intéressant c’est le marketing qui en est fait: dans les arguments, Dell met en avant les qualités du système en lui même: ça va de l’accessibilité en passant par la rapidité et la présence d’un Appstore façon Ubuntu, mais aussi et surtout… Steam, le client de jeu de Valve.

Steam ubuntu

Comme on le sait déjà, depuis quelques mois le développeur américain a rendu son client compatible GNU/Linux et a donc aussi entamé le portage des jeux Source (Half-Life, Counter Strike et toute la clique).

De plus en plus de titres (principalement Indie) qui étaient déjà disponibles sous GNU/Linux auparavant le sont donc désormais aussi par l’intermédiaire de Steam, de quoi remplir facilement leur catalogue dans un premier temps, immanquablement ça en fait un argument commercial concret.

Ça va faire déjà plusieurs mois que les barrières entre le jeu pour PC et les distributions GNU/Linux s’amincissent, voir même plusieurs années si l’on considère la bonne volonté de certains développeurs indépendants qui sortent des titres compatibles avec le duo Gnou-Manchot (beaucoup diront que “Linux” n’était pas compatible avec les jeux, alors que c’était en fait l’inverse).

Dans la foulée on va aussi citer certaines initiatives comme le Humble Bundle: payez ce que vous voulez pour un pack de jeux sans DRM compatibles Windows, GNU/Linux, Mac et même Android, là aussi on parle de jeux qui tournent nativement sous GNU/Linux, sans passer par une couche de compatibilité Windows (Wine) avec laquelle les résultats sont très variables d’un titre à l’autre.

L’initiative de Valve, maintenant des fabricants et de plus en plus des développeurs en général prend en partie racine dans le rejet de Windows 8, le dernier né de Microsoft, qui a rendu à tord où à raison tout ce beau monde septique vis à vis du système d’exploitation que beaucoup pensaient indétrônable quand il s’agissait de jeu sur PC.