diff --git a/.gitignore b/.gitignore index dbf24f4..4aaa8e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,20 @@ .idea .DS_Store -dist +build + +## CMake + +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps ## C diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..de0320a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required(VERSION 3.12) +project( + Mirage + VERSION 1.0.0 + HOMEPAGE_URL https://github.com/TravisWheelerLab/Mirage +) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build) + +add_executable( + MultiSeqNW + + src/MultiSeqNW.c +) +target_link_libraries(MultiSeqNW m) +install(TARGETS MultiSeqNW RUNTIME) + +add_executable( + ExonWeaver + + src/ExonWeaver.c + src/BasicBio.c +) +target_link_libraries(ExonWeaver m) +install(TARGETS ExonWeaver RUNTIME) + +add_executable( + FastMap2 + + src/FastMap2.c + src/BasicBio.c +) +target_link_libraries(FastMap2 m) +install(TARGETS FastMap2 RUNTIME) + +# Custom target for handling dependencies, Perl scripts, and shell scripts. We +# just move all these files to the build directory to aid in distribution and +# installation. These will be automatically run by the build. + +add_custom_target( + build-perl ALL + COMMAND cp + ${CMAKE_SOURCE_DIR}/src/*.pl + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ + COMMAND cp + ${CMAKE_SOURCE_DIR}/src/*.pm + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ +) + +add_custom_target( + build-shell ALL + COMMAND cp + ${CMAKE_SOURCE_DIR}/src/*.sh + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ +) + +add_custom_target( + build-dependencies ALL + COMMAND ./install-dependencies.sh + VERBATIM +) diff --git a/Makefile b/Makefile deleted file mode 100644 index c1cef6b..0000000 --- a/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -C_FLAGS := -O2 - -BUILD_DIR := build -DIST_DIR := dist -SRC_DIR := src - -.PHONY: build -build: ${BUILD_DIR}/FastMap2 ${BUILD_DIR}/ExonWeaver ${BUILD_DIR}/MultiSeqNW - -.PHONY: dist -dist: build - mkdir -p dist/ - cp ${BUILD_DIR}/FastMap2 ${DIST_DIR}/ - cp ${BUILD_DIR}/ExonWeaver ${DIST_DIR}/ - cp ${BUILD_DIR}/MultiSeqNW ${DIST_DIR}/ - cp ${SRC_DIR}/*.pl ${DIST_DIR}/ - cp ${SRC_DIR}/*.pm ${DIST_DIR}/ - cp LICENSE ${DIST_DIR}/ - cp README.md ${DIST_DIR}/ - -.PHONY: check -check: build - @echo "No checks yet" - -.PHONY: clean -clean: - rm -rf ${BUILD_DIR} - rm -rf ${DIST_DIR} - -${BUILD_DIR}/FastMap2: ${SRC_DIR}/FastMap2.c ${SRC_DIR}/BasicBio.c - mkdir -p ${BUILD_DIR} - ${CC} ${C_FLAGS} -o $@ $^ -lm - -${BUILD_DIR}/ExonWeaver: ${SRC_DIR}/ExonWeaver.c ${SRC_DIR}/BasicBio.c - mkdir -p ${BUILD_DIR} - ${CC} ${C_FLAGS} -o $@ $^ -lm - -${BUILD_DIR}/MultiSeqNW: ${SRC_DIR}/MultiSeqNW.c - mkdir -p ${BUILD_DIR} - ${CC} ${C_FLAGS} -o $@ $^ -lm - -# This Makefile knows how to build the project -# web site, which mostly consists of converting -# Markdown files to HTML. - -PAGE_INPUTS := $(shell find docs -type f -name '*.md') -PAGE_OUTPUTS := $(PAGE_INPUTS:.md=.html) - -HEADER := docs/media/header.html - -SITE_TITLE := [Mirage] -PANDOC := pandoc -s -H ${HEADER} - -.PHONY: docs -docs: ${PAGE_OUTPUTS} - -.PHONY: serve -serve: - @echo "Serving on http://localhost:8080" - @echo "Use ctrl-c to terminate the server" - @python3 -m http.server -d docs/ 8080 - -%.html: %.md ${HEADER} - @echo "building $<" - @${PANDOC} -M pagetitle:"/$(@D) ${SITE_TITLE}" -o "$@" "$<" diff --git a/README.md b/README.md index b285680..dff65c7 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ Multiple-sequence IsofoRm Alignment tool Guided by Exon boundaries. ## Dependencies Mirage has no build dependencies beyond the C standard library, but it does have -several runtime dependencies. These are described below. Executables should -exist somewhere in the user's `PATH`. +several runtime dependencies. These are listed below. The build process will +include suitable versions of each in the build output, so there is no need to +install them manually. **blat** - @@ -16,20 +17,21 @@ exist somewhere in the user's `PATH`. **tblastn** - -Appropriate versions of these are included in the `dependencies` directory of -the repository. The `SETUP.pl` script will build and install them. - ## Build -Building Mirage requires a modern C compiler. Use the `CC` environment variable -to control the compiler used. Set the `WORK_DIR` environment variable to control -where the binaries end up, the default is `dist`. +We use CMake to build Mirage. The following commands will place everything +needed to run Mirage in the `build/` directory. -Then, building is as simple as running `make`. +``` +cmake . +make +``` ## Installation -Once the build is complete, run `make install` to copy binaries. Use the -`PREFIX` environment variable to control the install location. The default -location is `/usr/local`. + The software can be "installed" simply by adding the `build/` directory to the + `PATH`. Optionally, it can be relocated first (for example, to `/opt/`). + +## Usage +TODO diff --git a/SETUP.pl b/SETUP.pl deleted file mode 100755 index ac668a2..0000000 --- a/SETUP.pl +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env perl -# -# ABOUT: This script is used to set up the directory for running -# mirage.pl. It verifies that all required programs are -# accessible and correctly compiled. -# -use warnings; -use strict; -use Cwd; - - -my $argcheck=0; -my $force=0; -while ($argcheck < scalar(@ARGV)) { - if (lc($ARGV[$argcheck]) eq '-force') { - $force=1; - } else { - print "\n Unrecognized option '$ARGV[$argcheck]' ignored.\n\n"; - } - $argcheck++; -} - - -# If there's already a link to mirage2, we'll kill it, just in case -# it doesn't look like it's safe to try miragery -if (-e 'mirage2') { system("rm \"mirage2\""); } - - -# The name of the spaln folder (at the top for ease of adjustment) -my $hsiDir = 'dependencies/hsi-1.0.0'; -my $spalnDir = 'dependencies/spaln2.3.3'; -my $blatDir = 'dependencies/blat'; -my $tbnDir = 'dependencies/tblastn'; -my $hsiTar = $hsiDir.'.tgz'; -my $spalnTar = $spalnDir.'.tgz'; -my $blatTar = $blatDir.'.tgz'; -my $tbnTar = $tbnDir.'.tgz'; - - -# Where we are RIGHT NOW -my $startDir = getcwd; -$startDir =~ s/\/$//; - - -# Check that all files are where we need them -my @srcFiles; -push(@srcFiles,'src/BasicBio.c'); -push(@srcFiles,'src/BasicBio.h'); -push(@srcFiles,'src/BureaucracyMirage.pm'); -push(@srcFiles,'src/ExonWeaver.c'); -push(@srcFiles,'src/FastMap2.c'); -push(@srcFiles,'src/FinalMSA.pl'); -push(@srcFiles,'src/Mirage2.pl'); -push(@srcFiles,'src/MultiSeqNW.c'); -push(@srcFiles,'src/MultiSeqNW.h'); -push(@srcFiles,'src/MapsToMSAs.pl'); -push(@srcFiles,'src/Oasis.pl'); -push(@srcFiles,'src/Quilter2.pl'); -push(@srcFiles,'src/run_mirage2.sh'); -push(@srcFiles,'src/run_oasis.sh'); -foreach my $file (@srcFiles) { - if (!(-e $file)) { die "\n Failed to locate critical file '$file'\n\n"; } -} - - -# Run the mirage makefile -print "\n Compiling mirage files\n\n"; -chdir("src") || die "\n Failed to enter directory 'src'\n\n"; -if (system("make")) { die "\n Failed to compile C source files\n\n"; } - - -# For the other programs included in the package, check to see if they're -# already available before we go through the trouble of setting them up - - -# Now we need to get easel unpacked and setup, too -chdir($startDir); -if (-e $hsiTar) { - - if (system("tar -xzf $hsiTar -C inc/")) { die "\n Failed to expand '$hsiTar'\n\n"; } - - # Make and make install - chdir($hsiDir) || die "\n Failed to enter directory '$hsiDir'\n\n"; - print "\n Compiling hsi tools\n\n"; - if (system("make")) { die "\n Failed to compile hsi library\n\n"; } - -} - - -# Unpack Spaln, if necessary -chdir($startDir); -if (-e $spalnTar) { - - if (system("tar -xzf $spalnTar -C inc/")) { die "\n Failed to expand file '$spalnTar'\n\n"; } - - # Configure and make SPALN - chdir("$startDir/$spalnDir/src") || die "\n Failed to enter directory '$spalnDir/src'\n\n"; - print "\n Configuring and compiling spaln\n\n"; - if (system("./configure")) { die "\n Failed to configure 'spaln'\n\n"; } - if (system("make")) { die "\n Failed to make 'spaln'\n\n"; } - -} - - -# Unpack BLAT -chdir($startDir); -if (-e $blatTar) { - if (system("tar -xzf $blatTar -C inc/")) { die "\n Failed to expand '$blatTar'\n\n"; } -} - - -# Unpack tblastn -if (-e $tbnTar) { - if (system("tar -xzf $tbnTar -C inc/")) { die "\n Failed to expand '$tbnTar'\n\n"; } -} - - -# If everything went well, we can go ahead an clear out the -# spaln and easel tarballs -system("rm $hsiTar") if (-e $hsiTar); -system("rm $spalnTar") if (-e $spalnTar); -system("rm $blatTar") if (-e $blatTar); -system("rm $tbnTar") if (-e $tbnTar); - -# Create a symbolic link to the mirage-running shell script -my $MirageLink = "ln -s src/run_mirage2.sh mirage2"; -if (system($MirageLink)) { die "\n Failed to create symbolic link to src/run_mirage2.sh\n\n"; } - -# Create a symbolic link for running bazaar -my $BazaarLink = "ln -s src/run_bazaar.sh bazaar"; -if (system($BazaarLink)) { die "\n Failed to create symbolic link to src/run_bazaar.sh\n\n"; } - -# Create a symbolic link for running oasis -my $OasisLink = "ln -s src/run_oasis.sh oasis"; -if (system($OasisLink)) { die "\n Failed to create symbolic link to src/run_oasis.sh\n\n"; } - -# Happy mirage-ing! -print "\n Setup completed successfully!\n\n"; -1; - diff --git a/install-dependencies.sh b/install-dependencies.sh new file mode 100755 index 0000000..2407a3a --- /dev/null +++ b/install-dependencies.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env sh + +set -e + +# Note: This script is run by the CMake build and there should be no reason to +# run it manually except for development and testing purposes. + +# Note: when upgrading dependencies, be sure to update the base file names in +# the block below, where appropriate. + +HSI_NAME=hsi-1.0.0 +SPALN_NAME=spaln2.3.3 +BLAT_NAME=blat +TBLASTN_NAME=tblastn + +HSI_BASE=hsi +SPALN_BASE=spaln +BLAT_BASE=blat +TBLASTN_BASE=tblastn + +DEPS_DIR=dependencies + +HSI_DIR=${DEPS_DIR}/${HSI_NAME} +SPALN_DIR=${DEPS_DIR}/${SPALN_NAME} +BLAT_DIR=${DEPS_DIR}/${BLAT_NAME} +TBLASTN_DIR=${DEPS_DIR}/${TBLASTN_NAME} + +HSI_TAR=${HSI_DIR}.tgz +SPALN_TAR=${SPALN_DIR}.tgz +BLAT_TAR=${BLAT_DIR}.tgz +TBLASTN_TAR=${TBLASTN_DIR}.tgz + +if [ ! -d build/ ]; +then + echo "No build found, see README" + exit 1 +fi + +# Add hsi to build +if [ ! -d build/${HSI_NAME} ]; +then + tar -xf $HSI_TAR -C $DEPS_DIR + pushd $HSI_DIR + cmake . && make + popd + mv $HSI_DIR build/${HSI_BASE} +else + echo "Skipping hsi" +fi + +# Add spaln to build +if [ ! -d build/${SPALN_NAME} ]; +then + tar -xf $SPALN_TAR -C dependencies/ + pushd $SPALN_DIR + ./configure && make + popd + mv $SPALN_DIR build/${SPALN_BASE} +else + echo "Skipping spaln" +fi + +# Add blat to build +if [ ! -d build/${BLAT_NAME} ]; +then + tar -xf $BLAT_TAR -C dependencies/ + mv $BLAT_DIR build/${BLAT_BASE} +else + echo "Skipping blat" +fi + +# Add tblastn to build +if [ ! -d build/${TBLASTN_NAME} ]; +then + tar -xf $TBLASTN_TAR -C dependencies + mv $TBLASTN_DIR build/${TBLASTN_BASE} +else + echo "Skipping tblastn" +fi