Bootstrap: docker From: ubuntu:22.04 %labels Author ATGC Tool MOTIF Version 1.0 %environment export LC_ALL=C.UTF-8 export LANG=C.UTF-8 export PATH="/opt/motif/bin:$PATH" %post set -eux apt-get update apt-get install -y --no-install-recommends \ ca-certificates \ git \ build-essential \ g++ \ make \ zlib1g-dev \ libgecode-dev \ python3 \ python3-pip \ bash \ coreutils \ zip # Replace this URL with the public repository you will create for MOTIF runtime. MOTIF_REPO_URL="https://gite.lirmm.fr/atgc/atgc_motif.git" git clone --depth 1 "${MOTIF_REPO_URL}" /opt/motif # Compatibility patch for legacy libSSA code with Gecode >= 6 (Ubuntu 22.04+). python3 - <<'PY' from pathlib import Path hpp = Path("/opt/motif/libSSA/src/seqGenerator.hpp") cpp = Path("/opt/motif/libSSA/src/seqGenerator.cpp") src_makefile = Path("/opt/motif/libSSA/src/Makefile") ssa_makefile = Path("/opt/motif/libSSA/src/SSA/Makefile") if not hpp.exists() or not cpp.exists(): raise SystemExit(0) hpp_text = hpp.read_text(encoding="utf-8") cpp_text = cpp.read_text(encoding="utf-8") original_hpp = hpp_text original_cpp = cpp_text hpp_text = hpp_text.replace( " CpSeqGeneratorCore(bool share, CpSeqGeneratorCore& s) ;", " CpSeqGeneratorCore(CpSeqGeneratorCore& s) ;", ) hpp_text = hpp_text.replace( " copy(bool share) ;", " copy(void) ;", ) if "default_options()" not in cpp_text: cpp_text = cpp_text.replace( "#include \n\n", "#include \n\n" "namespace {\n" "const Gecode::SizeOptions& default_options() {\n" "\tstatic Gecode::SizeOptions options(\"CpSeqGeneratorCore\");\n" "\treturn options;\n" "}\n" "}\n\n", 1, ) cpp_text = cpp_text.replace( "CpSeqGeneratorCore::CpSeqGeneratorCore( float const pwm[][4], int const pwmWidth, float const minThreshold ) :\n" "\t\tsequence( *this, pwmWidth, 0, 3 ), scores_by_position( *this, pwmWidth )", "CpSeqGeneratorCore::CpSeqGeneratorCore( float const pwm[][4], int const pwmWidth, float const minThreshold ) :\n" "\t\tScript(default_options()), sequence( *this, pwmWidth, 0, 3 ), scores_by_position( *this, pwmWidth )", ) cpp_text = cpp_text.replace( "CpSeqGeneratorCore::CpSeqGeneratorCore(bool share, CpSeqGeneratorCore& s) : Script(share,s) {\n" "\tsequence.update(*this, share, s.sequence);\n" "}", "CpSeqGeneratorCore::CpSeqGeneratorCore(CpSeqGeneratorCore& s) : Script(s) {\n" "\tsequence.update(*this, s.sequence);\n" "\tscores_by_position.update(*this, s.scores_by_position);\n" "}", ) cpp_text = cpp_text.replace( "CpSeqGeneratorCore::copy(bool share) {\n" "\treturn new CpSeqGeneratorCore(share,*this);\n" "}", "CpSeqGeneratorCore::copy(void) {\n" "\treturn new CpSeqGeneratorCore(*this);\n" "}", ) if "CpSeqGeneratorCore(bool share, CpSeqGeneratorCore& s)" in hpp_text: raise RuntimeError("Failed to patch seqGenerator.hpp cloning constructor for Gecode >= 6.") if "copy(bool share)" in hpp_text: raise RuntimeError("Failed to patch seqGenerator.hpp copy signature for Gecode >= 6.") if "Script(share,s)" in cpp_text: raise RuntimeError("Failed to patch seqGenerator.cpp Script clone constructor for Gecode >= 6.") if "copy(bool share)" in cpp_text: raise RuntimeError("Failed to patch seqGenerator.cpp copy() signature for Gecode >= 6.") if hpp_text != original_hpp: hpp.write_text(hpp_text, encoding="utf-8") if cpp_text != original_cpp: cpp.write_text(cpp_text, encoding="utf-8") if src_makefile.exists(): src_text = src_makefile.read_text(encoding="utf-8") original_src = src_text src_text = src_text.replace( "CFLAGS=-Wall -Wextra -O3 -march=native -I$(CURDIR)", "CFLAGS=-std=gnu++14 -Wall -Wextra -O3 -march=native -I$(CURDIR)", ) src_text = src_text.replace( "$(CC) $(CFLAGS) $(DIR_GECODE_H) $(DIR_GECODE_LIB) $(GECODE_LINKER) -o $@ $^ -Ikseq -lz -lrt", "$(CC) $(CFLAGS) $(DIR_GECODE_H) -o $@ $^ $(DIR_GECODE_LIB) $(GECODE_LINKER) -Ikseq -lz -lrt", ) if "$(DIR_GECODE_LIB) $(GECODE_LINKER) -o $@ $^" in src_text: raise RuntimeError("Failed to patch libSSA/src/Makefile link order for Gecode.") if src_text != original_src: src_makefile.write_text(src_text, encoding="utf-8") if ssa_makefile.exists(): ssa_text = ssa_makefile.read_text(encoding="utf-8") original_ssa = ssa_text ssa_text = ssa_text.replace( "CFLAGS=-W -Wall -pedantic -pedantic-errors -O9 -DNDEBUG", "CFLAGS=-std=gnu++14 -W -Wall -pedantic -O9 -DNDEBUG", ) ssa_text = ssa_text.replace("-pedantic-errors", "") if "CFLAGS=" in ssa_text and "-std=" not in ssa_text: ssa_text = ssa_text.replace("CFLAGS=", "CFLAGS=-std=gnu++14 ", 1) if "-pedantic-errors" in ssa_text: raise RuntimeError("Failed to patch SSA/Makefile pedantic flags for modern compilers.") if ssa_text != original_ssa: ssa_makefile.write_text(ssa_text, encoding="utf-8") PY if [ -f /opt/motif/requirements.txt ]; then python3 -m pip install --no-cache-dir -r /opt/motif/requirements.txt fi # Build searchMotif if not already provided by the runtime repository. if [ ! -x /opt/motif/libSSA/bin/searchMotif ]; then mkdir -p /opt/motif/libSSA/bin make -C /opt/motif/libSSA/src DIR_GECODE_LIB= DIR_GECODE_H= ../bin/searchMotif fi test -x /opt/motif/libSSA/bin/searchMotif chmod +x /opt/motif/bin/motif-run apt-get clean rm -rf /var/lib/apt/lists/* %runscript exec /opt/motif/bin/motif-run "$@" %test test -x /opt/motif/bin/motif-run test -x /opt/motif/libSSA/bin/searchMotif /opt/motif/bin/motif-run --help