LinuxCNC / linuxcnc

LinuxCNC controls CNC machines. It can drive milling machines, lathes, 3d printers, laser cutters, plasma cutters, robot arms, hexapods, and more.
http://linuxcnc.org/
GNU General Public License v2.0
1.81k stars 1.16k forks source link

Build system doesn't use --prefix= properly #216

Open bjornfor opened 7 years ago

bjornfor commented 7 years ago

Here are the steps I follow to reproduce the issue:

$ cd linuxcnc/src
$ ./autogen.sh
$ ./configure --with-realtime=uspace --prefix=$PWD/_install
$ make
$ make install
(error due to trying to install files in /etc)

This is what I expected to happen:

make install succeeds by placing all artifacts in the --prefix=$PWD/_install directory.

This is what happened instead:

Installation fails due to

  1. build system wrongly forcing user to set DESTDIR -- working around by setting DESTDIR=/
  2. use of hardcoded /etc directory a few places that bypasses the given --prefix=

With this small build system issue fixed, I/we will be close to having LinuxCNC packaged in Nix/nixpkgs.

samrose commented 5 years ago

has anyone ever gotten linuxcnc packaged for nix/nixpkgs?

zultron commented 5 years ago

I've had a lot of trouble with ${prefix} in the build system, too. I think the issue stems from the build system's history. The original build system looked a lot like many EDA and CAD build systems I worked with in the 1990s, where everything revolved around a $FOO_HOME variable. Later, the Autoconf configuration was added, but the build system was kept mostly unchanged by interchanging ${prefix} and ${EMC_HOME}. While this does work, it causes subtle bugs in some cases.

There was some work done in Machinekit to convert over to CMake. One main contributor to that effort was a NixOS user. There should be some breadcrumbs to follow in https://github.com/machinekit/machinekit/issues/336#issuecomment-122710432 .

MarcWeber commented 3 years ago

You still need tkimg etc. The code below works. Linuxcnc even starts up. You also need module for /etc/* files. But I still have issues running the CNC. If anybody is interested in helping testing this let me know.

{ python2Full
, stdenv
, gcc6Stdenv
, lib
, fetchFromGitHub

, wrapGAppsHook
, gobject-introspection
, makeWrapper
, readline6
, automake, autoconf, libtool,  pkgconfig, libtirpc, libmodbus, libusb1, gtk2, gtk3
, glib
, boost17x
, ps
, procps
, utillinux
, psmisc
, gettext
, intltool
, tk, tcl
, bwidget # TODO make executables find it
, tkimg
, tclx
, libGLU
, xlibs
, xorg
, pango, cairo
, linuxHeaders
} :

    let pythonEnv = 
      (python2Full.withPackages (ps: [
ps.Yapps2 ps.pycairo ps.cairocffi ps.cairosvg ps.tkinter ps.boost ps.pygobject3 ps.pygtk

    ])); in
    stdenv.mkDerivation {

    hardeningDisable = [ "all" ]; #TODO ? use patch instead ?

    # problems:
    # python pango/ cairo
    # import pango
    # import cairo ok

# import pygtk
# pygtk.require('2.0')
# import gtk
# import pango

    enableParalellBuilding = true;

    name = "linuxcnc-2.9-git";

    # # branch:master 2021-03-05 (2.9 pre)
    src = fetchFromGitHub {
      owner = "LinuxCNC";
      repo = "linuxcnc";
      rev = "578012bba16b807401f7bcae4390c49e1e90908a";
      sha256="1p0rq9pm97fdswxniwmfhmz11my654apnzb85fz4jklgxssw9kx1";
    };

    # src = fetchgit {
    #   url = "git://github.com/linuxcnc/linuxcnc.git";
    #   rev = "578012bba16b807401f7bcae4390c49e1e90908a";
    #   # date = "2021-03-05T16:05:06+00:00";
    #   sha256 = "1p0rq9pm97fdswxniwmfhmz11my654apnzb85fz4jklgxssw9kx1";
    # };

    nativeBuildInputs = [
        wrapGAppsHook
      gobject-introspection
    ];

    buildInputs = [
      makeWrapper
      readline6
      automake autoconf gettext libtool  pkgconfig libtirpc libmodbus libusb1 
      gtk2 pango cairo
      glib
      boost17x
      ps
      procps
      utillinux
      psmisc
      intltool
      tk tcl
      bwidget # TODO make executables find it
      tkimg
      tclx
      libGLU
      xlibs.libXmu

      pythonEnv
  ];

      # configure: WARNING: The LinuxCNC binary you are building may not be
      # distributable due to a license incompatibility with LinuxCNC (some portions
      # GPL-2 only) and Readline version 6 and greater (GPL-3 or later).
      # configure: error: To configure LinuxCNC in this way, you must
      # invoke configure with "--enable-non-distributable=yes".  Note that on
      # Debian-based systems, you may be able to use libreadline-gplv2-dev instead.

    # for uts kernel
    # linuxHeaders # ?
    # export KERNELDIR=${linuxHeaders};

    # --with-realtime=uspace \  -> stepconf -> simualtion version only?
    configurePhase = ''
    export KERNELDIR=${linuxHeaders};
    export TCLLIBPATH="${bwidget}/lib ${tkimg}/lib ${tclx}/lib"
    cd src
    ./autogen.sh
    ./configure  \
      --with-tkConfig=${tk}/lib/tkConfig.sh \
      --with-tclConfig=${tcl}/lib/tclConfig.sh \
      --with-realtime=uspace \
      --disable-run-place \
      "--enable-non-distributable=yes" \
      --prefix=$out

      sed -i \
        -e 's/chown.*//' \
        -e 's/-o root//g' \
        -e 's/ -m [0-9]\+//g' \
        Makefile
    '';

    installPhase = ''
      mkdir $out
      make install DESTDIR=$out
      set -x

      link(){
        local from="$1"
        local to="$2"
        local b
        echo "calling link $from $to"

        for x in "$from"/*; do
          b="$(basename "$x")"
          if [ -d "$to/$b" ]; then
            link "$x" "$to/$b"
          else
            ln -s "$x" "$to/$b"
          fi
        done
      }

      link "$out/$out" "$out"
      gappsWrapperArgsHook

      for p in $out/bin/*; do
        wrapGApp "$p" \
          --prefix PATH ':' $PATH \
          --prefix TCLLIBPATH ' ' "$TCLLIBPATH $out/lib $out/lib/tcltk/linuxcnc" \
          --prefix PYTHONPATH ':' "$out/${pythonEnv}/lib/python2.7/site-packages" \
          --prefix LD_LIBRARY_PATH ':' "${xorg.libXScrnSaver}/lib"
      done

    '';
  }
{ config, pkgs, lib, ... }:

with lib;

let
  cfg = config.programs.linuxcnc;

in

{

  options = {

    programs.linuxcnc.enable = mkEnableOption "enable linuxcnc";

    programs.linuxcnc.package = mkOption {
      type = types.package;
      default = pkgs.linuxcnc29;
    };

  };

  config = mkIf cfg.enable {

    environment.etc."init.d/realtime".source =  "${cfg.package}/etc/init.d/realtime";
    environment.etc."X11/app-defaults/TkLinuxCNC".source =  "${cfg.package}/etc/X11/app-defaults/TkLinuxCNC";
    environment.etc."linuxcnc/rtapi.conf".source =  "${cfg.package}${cfg.package}/etc/linuxcnc/rtapi.conf";
    environment.systemPackages = [ cfg.package ];

    security.wrappers.rtapi_app = {
      group = "root";
      owner = "root";
      program = "rtapi_app";
      source = "${cfg.package}/bin/rtapi_app";
      # group = cfg.setgidGroup;
      setuid = false;
      setgid = true;
    };

  };

}
MarcWeber commented 3 years ago

https://github.com/MarcWeber/nixpkgs/tree/e2/linuxcnc I totally failed wit realtime stuff. When running as root it shows 'using realtime=posix' or such. But even measuring the jittering (stepconf) The very old i686 machine I have starts hanging. Without realitme (uspace) it seems to work partially. I was able to move X-axis in stepconf.

A script like below can be used to push a i686 system built on modern fast machine to a slow old one:

update_linuxcnc(){
  export NIX_PATH=nixos=/etc/nixos/nixpkgs/nixos:nixpkgs=/etc/nixos/nixpkgs:nixos-config=/etc/nixos/setups/u/configuration.nix
  nix-build --out-link /tmp/u '<nixpkgs/nixos>' --argstr system 'i686-linux' -A system || return
  echo build ok
  l=$(readlink /tmp/u)
  nix-copy-closure --to  root@192.168.178.103 $l || return
  echo copy ok
  echo "$l/bin/switch-to-configuration switch" | ssh root@192.168.178.103 || return
  echo switch ok
}
mattywillo commented 2 years ago

This issue is a bit old but I've made progressing packaging LinuxCNC for NixOS, cc @MarcWeber @bjornfor if you are still interested.

Currently jogging machines around via a Mesa card and PREEMPT_RT, on x86_64. I've also packaged a PREEMPT_RT Rpi4 kernel and its moving there as well. The main utility apps seem to work, and linuxcnc itself works with AXIS. The other GUIs need a bit more attention.

There's a fair amount of patching around the build system and FHS paths required though, so not sure if it's worth upstreaming them just for NixOS, as the NixOS package requires special patching anyway, to account for setuid.

My repo and notes are here along with an example Rpi4 config.