diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..007b3ed --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +*.swp +~* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3819313 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.swp +*.swo diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c0b7c27 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,140 @@ +FROM ubuntu:jammy + +ENV FREECAD_VERSION="FreeCAD-1-0" + +LABEL MAINTAINER="xxxx@example.com" +LABEL DESCRIPTION="A docker image to build FreeCAD locally" +LABEL VERSION="$FREECAD_VERSION" + +SHELL ["/bin/bash", "-c"] + +WORKDIR /tmp + +# REF: https://wiki.freecad.org/Compile_on_Linux + +# #!/bin/sh +# sudo add-apt-repository --enable-source ppa:freecad-maintainers/freecad-daily && sudo apt-get update +# sudo apt-get build-dep freecad-daily +# sudo apt-get install freecad-daily + +# git clone --recurse-submodules https://github.com/FreeCAD/FreeCAD.git freecad-source +# mkdir freecad-build +# cd freecad-build +# cmake -DPYTHON_EXECUTABLE=/usr/bin/python3 -DFREECAD_USE_PYBIND11=ON ../freecad-source +# make -j$(nproc --ignore=2) + +ENV DEBIAN_FRONTEND=noninteractive + +# Build tools, and misc supporting tools +RUN apt update && \ + apt install -y build-essential cmake libtool lsb-release git + +# Python3 +RUN apt install -y python3 swig + +# Boost libraries +RUN apt install -y \ + libboost-dev \ + libboost-date-time-dev \ + libboost-filesystem-dev \ + libboost-graph-dev \ + libboost-iostreams-dev \ + libboost-program-options-dev \ + libboost-python-dev \ + libboost-regex-dev \ + libboost-serialization-dev \ + libboost-thread-dev + +# Coin libraries +RUN apt install -y libcoin-dev libcoin-doc libcoin-runtime + +# Misc libraries +RUN apt install -y \ + libeigen3-dev \ + libgts-bin \ + libgts-dev \ + libkdtree++-dev \ + libmedc-dev \ + libopencv-dev \ + libproj-dev \ + libvtk9-dev \ + libx11-dev \ + libxerces-c-dev \ + libyaml-cpp-dev \ + libzipios++-dev + +# Python 3 and Qt5 +RUN apt install -y \ + libpyside2-dev \ + libqt5opengl5-dev \ + libqt5svg5-dev \ + libqt5x11extras5-dev \ + libqt5xmlpatterns5-dev \ + libshiboken2-dev \ + pyqt5-dev-tools \ + pyside2-tools \ + python3-dev \ + python3-matplotlib \ + python3-packaging \ + python3-pivy \ + python3-ply \ + python3-pyside2.qtcore \ + python3-pyside2.qtgui \ + python3-pyside2.qtnetwork \ + python3-pyside2.qtsvg \ + python3-pyside2.qtwebchannel \ + python3-pyside2.qtwebengine \ + python3-pyside2.qtwebenginecore \ + python3-pyside2.qtwebenginewidgets \ + python3-pyside2.qtwidgets \ + qtbase5-dev \ + qttools5-dev \ + qtwebengine5-dev + +# OpenCascade +RUN apt install -y libocct*-dev occt-draw + +# Optional packges +RUN apt install -y \ + checkinstall \ + doxygen \ + graphviz \ + libsimage-dev \ + libspnav-dev + +# To fix compilation problems +RUN apt install -y \ + libhdf5-openmpi-dev \ + python3-pip + +# Known python dependencies +RUN python3 -m pip install ifcopenshell==0.8.0 + +# DEBUG C++ with gdb +RUN apt install -y gdb libcanberra-gtk-module libcanberra-gtk3-module +RUN python3 -m pip install gdbgui +ENV FREECAD_GDB_PORT=5000 +EXPOSE 5000 + +# DEBUG Python with winpdb +RUN apt install -y wxpython-tools +RUN python3 -m pip install winpdb-reborn +ENV FREECAD_WINPDB_PORT=51000 +ENV FREECAD_WINPDB_PWD=1234 +EXPOSE 51000 + +# These environment variable are set here to be used +# by the different container's scripts +ENV FREECAD_CONFIG_DIR="/root/.local/FreeCAD" +ENV FREECAD_BUILD_DIR="/mnt/build" +ENV FREECAD_SOURCE_DIR="/mnt/source" + +# Add the build & debug scripts +ADD add_files/build_FC.sh /root/build_FC.sh +ADD add_files/debug_FC_cpp.sh /root/debug_FC_cpp.sh +ADD add_files/debug_FC_python.sh /root/debug_FC_python.sh +ADD add_files/debug_FC_init.py /root/debug_FC_init.py + +WORKDIR /root + +# Note for later: May need -fPIC diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md index f656f25..fb273bb 100644 --- a/README.md +++ b/README.md @@ -1 +1,89 @@ -FreeCAD development & deployment with Docker. +# FreeCAD-docker + +This is a docker container intended to act as a build and run environment for +FreeCAD. + +It is based on [daviddaish/freecad_docker_env](https://gitlab.com/daviddaish/freecad_docker_env) + +The directories containing FreeCAD's source code and build are not included +inside the docker image. Instead, they are attached to the docker container +when you run the container. This allows the built code to have continuity +across different docker containers, reducing the time for a build to occur, and +allowing you to use your own editor/IDE outside of the container. + +The docker is not deployed and therefore you need to build it locally + +## Build the docker image + +You must edit the [run_docker.sh](run_docker.sh) to set the correct path to the `SOURCE_DIR`, `BUILD_DIR` and `CONF_DIR`. Then you can execute `run_docker.sh`: + +```shell +?> ./run_docker.sh +``` + +## Build FreeCAD + +Once the docker container has been created, you should have access to a command prompt that allows you to build your version of FreeCAD. + +```shell +docker> /root/build_freecad.sh +``` + +## Run FreeCAD + +Once you have build FreeCAD you can execute it with: + +```shell +docker> /mnt/build/bin/FreeCAD +``` + +>**For mac users:** +> +>In order to use the GUI, you must install [XQuartz](https://www.xquartz.org/). +> +>Then, open XQuartz with `open -a XQuartz`, and ensure "Allow connections from +>within network clients" is ticked, under the "Security" tab. This process was +>taken from this [blogpost](https://sourabhbajaj.com/blog/2017/02/07/gui-applications-docker-mac/). + +You will be able to find the mounted directories within the container in the +`/mnt` directory, named `/mnt/source`, `/mnt/build`, and `/mnt/files`. + +## Debug a FreeCAD Python workbench + +REF: [Python workbenches debugging](https://forum.freecad.org/viewtopic.php?t=35383) + +* Start winpdb + +```shell +docker> winpdb +``` + +* Start FreeCAD + +```shell +docker> /mnt/build/bin/FreeCAD --console --verbose /mnt/files/git/opensource/FreeCAD/src/Mod/BIM/Resources/importers/debug_importSH3D.py +``` + +## Developing the image + +### Build docker image + +Building the docker image might take several hours (depending on your connection). + +```shell +docker build -t registry.gitlab.com/daviddaish/freecad_docker_env:latest . +``` + +Note that, because of the size of the dependancies, docker may throw a `no space left on device` +error part way through the build. To reduce the likelyhood of this, ensure you have around 25GB +of space on your storage. You can also run `docker system prune` to free up space. + +### Pushing the docker image + +Prior to pushing, the image must be able to reliabily build the most recent +tags of the FreeCAD source code: `master`, `0.19_pre`, and `0.18.4`. + +```shell +docker login registry.gitlab.com +docker push registry.gitlab.com/daviddaish/freecad_docker_env:updates +``` diff --git a/add_files/build_FC.sh b/add_files/build_FC.sh new file mode 100755 index 0000000..4f229ae --- /dev/null +++ b/add_files/build_FC.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# +# This script will launch the build of FreeCAD. +# + +p_build_type="Debug" + +#------------------------------------------------------------------------------ +# FUNCTION: usage +#------------------------------------------------------------------------------ +usage() +{ + cat >&2 < $0 +?> $0 --debug + +Build FreeCAD in Rebug mode +?> $0 --release + +EOF +} + + +#============================================================================== +# +# MAIN PROGRAM SECTION. +# +#============================================================================== +options=$(getopt --alternative --name $(basename $0) --options "hdr" --longoptions help,debug,release -- $0 "$@") +if [ $? -ne 0 ]; then + usage + exit 1 +fi +eval set -- "$options" +while true; do + case "$1" in + -d|--debug) p_build_type="Debug" ;; + -r|--release) p_build_type="Release" ;; + -h|--help) usage; exit 0 ;; + --) shift; break ;; + esac + shift +done + +git config --global --add safe.directory ${FREECAD_SOURCE_DIR} + +set -e + +# NOTE: The PYTHON_LIBRARY is dependant on the base image used +# in the docker file. +cmake \ + -D PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.10.so.1.0 \ + -D PYTHON_INCLUDE_DIR=/usr/include/python3.10/ \ + -D PYTHON_EXECUTABLE=/usr/bin/python3 \ + -D FREECAD_USE_OCC_VARIANT="Official Version" \ + -D BUILD_QT5=ON \ + -D BUILD_FEM=ON \ + -D BUILD_SANDBOX=OFF \ + -D BUILD_DESIGNER_PLUGIN=ON \ + -D CMAKE_BUILD_TYPE=$p_build_type \ + -S ${FREECAD_SOURCE_DIR} \ + -B ${FREECAD_BUILD_DIR} + +pushd ${FREECAD_BUILD_DIR} +make -j $(nproc --ignore=1) diff --git a/add_files/debug_FC_cpp.sh b/add_files/debug_FC_cpp.sh new file mode 100755 index 0000000..8541914 --- /dev/null +++ b/add_files/debug_FC_cpp.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# +# This script starts both gdbgui and FreeCAD to debug CPP code +# +gdbgui --port $FREECAD_GDB_PORT --remote --project ${FREECAD_BUILD_DIR} --args ${FREECAD_BUILD_DIR}/bin/FreeCAD diff --git a/add_files/debug_FC_init.py b/add_files/debug_FC_init.py new file mode 100644 index 0000000..6716ffa --- /dev/null +++ b/add_files/debug_FC_init.py @@ -0,0 +1,30 @@ +# *************************************************************************** +# * Copyright (c) 2024 Julien Masnada * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +# This file is used to launch the debug process for the workbench + +import os +import rpdb2 +import FreeCAD as App + +rpdb2.start_embedded_debugger(os.getenv("FREECAD_WINPDB_PWD")) # by default port 51000 +doc = App.newDocument() +App.Console.PrintMessage("Set breakpoints and then launch your command\n") diff --git a/add_files/debug_FC_python.sh b/add_files/debug_FC_python.sh new file mode 100755 index 0000000..70d1cc0 --- /dev/null +++ b/add_files/debug_FC_python.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# This script will start both Winpdb and FreeCAD to debug a Python workbench +# +# TODO: How to use FREECAD_WINPDB_PORT? +winpdb & +${FREECAD_BUILD_DIR}/bin/FreeCAD /root/debug_FC_init.py diff --git a/run_docker.sh b/run_docker.sh new file mode 100755 index 0000000..5fce199 --- /dev/null +++ b/run_docker.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# FILE: run_docker.sh +# +# DESCRIPTION: This script builds the docker image necessary to +# build the FreeCAD source. +# +# REF: https://wiki.freecad.org/Compile_on_Docker + + +p_source_dir=~/git/opensource/FreeCAD +p_build_dir=~/git/opensource/FreeCAD-build +p_conf_dir=~/.config/FreeCAD +HOME_DIR=~/ + +#------------------------------------------------------------------------------ +# FUNCTION: usage +#------------------------------------------------------------------------------ +usage() +{ + cat >&2 < $0 + +EOF +} + +#============================================================================== +# +# MAIN PROGRAM SECTION. +# +#============================================================================== +options=$(getopt --alternative --name $(basename $0) --options "hc:b:s:" --longoptions help,config-dir:,build-dir:,source-dir: -- $0 "$@") +if [ $? -ne 0 ]; then + usage + exit 1 +fi +eval set -- "$options" +while true; do + case "$1" in + -c|--config-dir) shift; p_conf_dir=$1 ;; + -b|--build-dir) shift; p_build_dir=$1 ;; + -s|--source-dir) shift; p_source_dir=$1 ;; + -h|--help) usage; exit 0 ;; + --) shift; break ;; + esac + shift +done + +if [ ! -d "${p_conf_dir}" ]; then + usage + echo "Invalid '--config-dir'. No such file or directory" >&2 + exit 1 +fi + +if [ ! -d "${p_build_dir}" ]; then + usage + echo "Invalid '--build-dir'. No such file or directory" >&2 + exit 1 +fi + +if [ ! -d "${p_source_dir}" ]; then + usage + echo "Invalid '--source-dir'. No such file or directory" >&2 + exit 1 +fi + +echo "Building docker container ..." + +docker build -t local/freecad-docker:latest . + +if [ ! -d "${p_source_dir}" ]; then + mkdir -p "${p_source_dir}" + pushd "${p_source_dir}" + git clone https://github.com/FreeCAD/FreeCAD.git -d "${p_source_dir}" + exit 1 +fi +if [ ! -d "${p_build_dir}" ]; then + mkdir -p "${p_build_dir}" +fi + +echo "Enabling local X connections ..." +xhost +local: + +# make sure the port are in sinc with the Dockerfile +echo "Building from ${p_source_dir} ..." +docker run -it --rm \ + -p 5000:5000 \ + -p 51000:51000 \ + -v ${p_source_dir}:/mnt/source \ + -v ${p_build_dir}:/mnt/build \ + -v ${HOME_DIR}:/mnt/files \ + -v ${p_conf_dir}:/root/.local/FreeCAD \ + -e "DISPLAY" \ + -e "QT_X11_NO_MITSHM=1" \ + -v /tmp/.X11-unix:/tmp/.X11-unix:ro \ + local/freecad-docker:latest