diff --git a/.gitignore b/.gitignore index c916c20..a0b4a5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -libs/** build/** +install/** source-cache/** diff --git a/Makefile b/Makefile index a1f2439..4f98d86 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,9 @@ ROOT_DIR ?= ${PWD} # create necessary file structure SRC_CACHE = $(ROOT_DIR)/source-cache BUILD_DIR = $(ROOT_DIR)/build -LIBS_DIR = $(ROOT_DIR)/libs -IGNORE := $(shell mkdir -p $(SRC_CACHE) $(BUILD_DIR) $(LIBS_DIR)) +INSTALL_DIR = $(ROOT_DIR)/install +LD_LIBRARY_PATH=$(INSTALL_DIR)/lib +IGNORE := $(shell mkdir -p $(SRC_CACHE) $(BUILD_DIR) $(INSTALL_DIR)) # if no SONAME suffix is wanted, leave everything blank ifeq ($(strip $(SONAME_SUFFIX)),) @@ -27,10 +28,12 @@ fix_soname = grep -Rl '$(2)' $(BUILD_DIR)/$(1) | xargs sed -i "s/$(2)/$(3)/g"; .PHONY: clean +.EXPORT_ALL_VARIABLES: + all: octave clean: - rm -Rf $(BUILD_DIR) $(LIBS_DIR) $(SRC_CACHE) + rm -Rf $(BUILD_DIR) $(INSTALL_DIR) $(SRC_CACHE) ################################################################################ # @@ -48,16 +51,16 @@ $(SRC_CACHE)/openblas-$(OPENBLAS_VER).zip: && wget https://github.com/xianyi/OpenBLAS/archive/v$(OPENBLAS_VER).zip \ && mv v$(OPENBLAS_VER).zip openblas-$(OPENBLAS_VER).zip -$(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so: \ +$(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so: \ $(SRC_CACHE)/openblas-$(OPENBLAS_VER).zip cd $(BUILD_DIR) \ && unzip $(SRC_CACHE)/openblas-$(OPENBLAS_VER).zip \ && mv OpenBLAS-$(OPENBLAS_VER) openblas cd $(BUILD_DIR)/openblas \ && $(MAKE) BINARY=64 INTERFACE64=1 LIBNAMESUFFIX=$(SONAME_SUFFIX) \ - && $(MAKE) install PREFIX=$(LIBS_DIR) LIBNAMESUFFIX=$(SONAME_SUFFIX) + && $(MAKE) install PREFIX=$(INSTALL_DIR) LIBNAMESUFFIX=$(SONAME_SUFFIX) -openblas: $(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so +openblas: $(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so ################################################################################ @@ -80,9 +83,9 @@ $(SRC_CACHE)/suitesparse-$(SUITESPARSE_VER).tar.gz: && mv SuiteSparse-$(SUITESPARSE_VER).tar.gz \ suitesparse-$(SUITESPARSE_VER).tar.gz -$(LIBS_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so: \ +$(INSTALL_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so: \ $(SRC_CACHE)/suitesparse-$(SUITESPARSE_VER).tar.gz \ - $(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so + $(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so # unpack sources cd $(BUILD_DIR) \ && tar -xf $(SRC_CACHE)/suitesparse-$(SUITESPARSE_VER).tar.gz \ @@ -101,15 +104,15 @@ $(LIBS_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so: \ BLAS=-lopenblas$(_SONAME_SUFFIX) \ UMFPACK_CONFIG=-D'LONGBLAS=long' \ CHOLMOD_CONFIG=-D'LONGBLAS=long' \ - LDFLAGS='-L$(LIBS_DIR)/lib -L$(BUILD_DIR)/suitesparse/lib' \ + LDFLAGS='-L$(INSTALL_DIR)/lib -L$(BUILD_DIR)/suitesparse/lib' \ && $(MAKE) install \ - INSTALL=$(LIBS_DIR) \ + INSTALL=$(INSTALL_DIR) \ INSTALL_DOC=/tmp/doc \ LAPACK= \ BLAS=-lopenblas$(_SONAME_SUFFIX) \ - LDFLAGS='-L$(LIBS_DIR)/lib -L$(BUILD_DIR)/suitesparse/lib' + LDFLAGS='-L$(INSTALL_DIR)/lib -L$(BUILD_DIR)/suitesparse/lib' -suitesparse: $(LIBS_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so +suitesparse: $(INSTALL_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so ################################################################################ @@ -127,9 +130,9 @@ $(SRC_CACHE)/qrupdate-$(QRUPDATE_VER).tar.gz: cd $(SRC_CACHE) \ && wget http://downloads.sourceforge.net/project/qrupdate/qrupdate/1.2/qrupdate-$(QRUPDATE_VER).tar.gz -$(LIBS_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so: \ +$(INSTALL_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so: \ $(SRC_CACHE)/qrupdate-$(QRUPDATE_VER).tar.gz \ - $(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so + $(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so # unpack sources cd $(BUILD_DIR) \ && tar -xf $(SRC_CACHE)/qrupdate-$(QRUPDATE_VER).tar.gz \ @@ -141,10 +144,10 @@ $(LIBS_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so: \ && $(MAKE) install \ LAPACK="" \ BLAS="-lopenblas$(_SONAME_SUFFIX)" \ - FFLAGS="-L$(LIBS_DIR)/lib -fdefault-integer-8" \ - PREFIX=$(LIBS_DIR) + FFLAGS="-L$(INSTALL_DIR)/lib -fdefault-integer-8" \ + PREFIX=$(INSTALL_DIR) -qrupdate: $(LIBS_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so +qrupdate: $(INSTALL_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so ################################################################################ @@ -163,9 +166,9 @@ $(SRC_CACHE)/arpack-$(ARPACK_VER).tar.gz: && wget https://github.com/opencollab/arpack-ng/archive/$(ARPACK_VER).tar.gz \ && mv $(ARPACK_VER).tar.gz arpack-$(ARPACK_VER).tar.gz -$(LIBS_DIR)/lib/libarpack$(_SONAME_SUFFIX).so: \ +$(INSTALL_DIR)/lib/libarpack$(_SONAME_SUFFIX).so: \ $(SRC_CACHE)/arpack-$(ARPACK_VER).tar.gz \ - $(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so + $(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so # unpack sources cd $(BUILD_DIR) \ && tar -xf $(SRC_CACHE)/arpack-$(ARPACK_VER).tar.gz \ @@ -173,16 +176,17 @@ $(LIBS_DIR)/lib/libarpack$(_SONAME_SUFFIX).so: \ # build and install library cd $(BUILD_DIR)/arpack \ && ./bootstrap \ - && ./configure --prefix=$(LIBS_DIR) \ + && ./configure --prefix=$(INSTALL_DIR) \ + --libdir=$(INSTALL_DIR)/lib \ --with-blas='-lopenblas$(_SONAME_SUFFIX)' \ --with-lapack='' \ INTERFACE64=1 \ - LT_SYS_LIBRARY_PATH=$(LIBS_DIR)/lib \ - LDFLAGS='-L$(LIBS_DIR)/lib' \ + LT_SYS_LIBRARY_PATH=$(INSTALL_DIR)/lib \ + LDFLAGS='-L$(INSTALL_DIR)/lib' \ LIBSUFFIX='$(_SONAME_SUFFIX)' \ && $(MAKE) check && $(MAKE) install -arpack: $(LIBS_DIR)/lib/libarpack$(_SONAME_SUFFIX).so +arpack: $(INSTALL_DIR)/lib/libarpack$(_SONAME_SUFFIX).so ################################################################################ @@ -207,9 +211,11 @@ LDSUITESPARSE = \ -lsuitesparseconfig$(_SONAME_SUFFIX)' OCTAVE_CONFIG_FLAGS = \ - CPPFLAGS='-I$(LIBS_DIR)/include' \ - LDFLAGS='-L$(LIBS_DIR)/lib' \ - LD_LIBRARY_PATH='$(LIBS_DIR)/lib' \ + CPPFLAGS='-I$(INSTALL_DIR)/include' \ + LDFLAGS='-L$(INSTALL_DIR)/lib' \ + LD_LIBRARY_PATH='$(INSTALL_DIR)/lib' \ + --prefix=$(INSTALL_DIR) \ + --libdir='$(INSTALL_DIR)/lib' \ --enable-64 \ --with-blas='-lopenblas$(_SONAME_SUFFIX)' \ --with-amd='-lamd$(_SONAME_SUFFIX) \ @@ -233,17 +239,16 @@ $(SRC_CACHE)/octave-$(OCTAVE_VER).tar.gz: | grep -o 'http\S\+.tar.gz')) cd $(SRC_CACHE) && wget $(URL) -$(BUILD_DIR)/octave/run-octave: $(SRC_CACHE)/octave-$(OCTAVE_VER).tar.gz \ - $(LIBS_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so \ - $(LIBS_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so \ - $(LIBS_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so \ - $(LIBS_DIR)/lib/libarpack$(_SONAME_SUFFIX).so +$(INSTALL_DIR)/bin/octave: $(SRC_CACHE)/octave-$(OCTAVE_VER).tar.gz \ + $(INSTALL_DIR)/lib/libopenblas$(_SONAME_SUFFIX).so \ + $(INSTALL_DIR)/lib/libsuitesparseconfig$(_SONAME_SUFFIX).so \ + $(INSTALL_DIR)/lib/libqrupdate$(_SONAME_SUFFIX).so \ + $(INSTALL_DIR)/lib/libarpack$(_SONAME_SUFFIX).so cd $(BUILD_DIR) \ && tar -xf $(SRC_CACHE)/octave-$(OCTAVE_VER).tar.gz \ && mv octave-$(OCTAVE_VER) octave - export LD_LIBRARY_PATH=$(LIBS_DIR)/lib cd $(BUILD_DIR)/octave \ - && ./configure $(OCTAVE_CONFIG_FLAGS) && $(MAKE) \ - && $(MAKE) check LD_LIBRARY_PATH='$(LIBS_DIR)/lib' + && ./configure $(OCTAVE_CONFIG_FLAGS) && $(MAKE) install \ + && $(MAKE) check LD_LIBRARY_PATH='$(INSTALL_DIR)/lib' -octave: $(BUILD_DIR)/octave/run-octave +octave: $(INSTALL_DIR)/bin/octave diff --git a/README.md b/README.md index a3ec708..15daae8 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,19 @@ # GNU Octave enable-64 -This project targets compiling [GNU Octave](http://www.gnu.org/software/octave/) -using 64-bit indices on **Linux systems**. +This project targets compiling [GNU Octave][1] using 64-bit on +**Linux systems**. + ## For quick starters -If all GNU Octave -[build dependencies](https://www.gnu.org/software/octave/doc/interpreter/Build-Dependencies.html) -are installed, just type the following commands: +If all [GNU Octave build dependencies][2] are installed, just type the +following commands: + + git clone https://github.com/siko1056/GNU-Octave-enable-64.git + cd GNU-Octave-enable-64 + make + ./install/bin/octave -``` -git clone https://github.com/siko1056/GNU-Octave-enable-64.git -cd GNU-Octave-enable-64 -make -./build/octave/run-octave -``` ## More details @@ -25,31 +24,28 @@ compile - [SuiteSparse](http://www.suitesparse.com) (4.5.3), - [QRUPDATE](http://sourceforge.net/projects/qrupdate) (1.1.2), - [ARPACK-NG](https://github.com/opencollab/arpack-ng) (3.4.0), and -- [GNU Octave](http://www.gnu.org/software/octave/) (development version) +- [GNU Octave][1] (development version) using 64-bit indices. To get a quick overview about the library dependencies, the following figure visualizes them top-down: "The above requires all libraries below". -``` -+-------------------------------------------------------+ -| GNU Octave | -+-------------+-------------+-------------+-------------+ -| | SuiteSparse | QRUPDATE | ARPACK-NG | -| +-------------+-------------+-------------+ -| OpenBLAS | -+-------------------------------------------------------+ -``` - -> Notice: It is assumed, that the user of this Makefile is already capable of -> building the "usual" Octave development version! - -Means, that all other -[build dependencies](https://www.gnu.org/software/octave/doc/interpreter/Build-Dependencies.html) -(e.g. libtool, gfortran, ...) are properly installed on the system and, even -better, building the "usual" Octave development version runs flawless. -Building this project requires approximately **4 GB** disc space and **1 hour**, -depending on your system. + +-------------------------------------------------------+ + | GNU Octave | + +-------------+-------------+-------------+-------------+ + | | SuiteSparse | QRUPDATE | ARPACK-NG | + | +-------------+-------------+-------------+ + | OpenBLAS | + +-------------------------------------------------------+ + +> **Notice:** It is assumed, that the user of this Makefile is already +> capable of building the "usual" Octave development version! + +Means, that all other [GNU Octave build dependencies][2] (e.g. libtool, +gfortran, ...) are properly installed on the system and, even better, +building the "usual" Octave development version runs flawless. Building +this project requires approximately **4 GB** disc space and **1 hour**, +depending on your system and the number of parallel jobs `make -j`. Using this Makefile is especially of interest, if one pursues the following goals: @@ -61,67 +57,54 @@ Both abovementioned goals are archived by building and deploying the required libraries in an arbitrary directory **ROOT_DIR**. This directory can be set by calling the Makefile like: -``` -make ROOT_DIR=$HOME/some/path -``` + make ROOT_DIR=$HOME/some/path The internal directory structure relative to *ROOT_DIR* is: -``` -ROOT_DIR -|-- build # local build directory for each library -| |-- arpack -| |-- octave -| +-- ... -|-- libs # local replacement for system wide library -| |-- include # deployment, like /usr or /usr/local -| +-- lib -+-- source-cache # location for downloaded library sources - |-- arpack-$(VER).tar.gz - +-- ... -``` + ROOT_DIR + |-- build # local build directory for each library + | |-- arpack + | |-- octave + | +-- ... + |-- install # local installation path like `/usr` or `/usr/local` + | |-- bin + | |-- include + | +-- lib + +-- source-cache # location for downloaded library sources + |-- arpack-$(VER).tar.gz + +-- ... All required libraries are built according to this pattern: 1. Download the source code -2. Extract the source code to directory *ROOT_DIR/build* +2. Extract the source code to directory `ROOT_DIR/build` 3. Configure and build the library (sometimes with ugly hacks) 1. Ensure usage of 64-bit indices. - 2. Ensure the suffix "\_Octave64" in the library's - [SONAME](https://en.wikipedia.org/wiki/Soname). -4. Deploy the library in *ROOT_DIR/libs/lib* (sometimes with ugly hacks) + 2. Ensure the suffix `_Octave64` in the library's [SONAME][5]. +4. Deploy the library in `ROOT_DIR/install` (sometimes with ugly hacks) To guarantee the usage of the self compiled libraries, even in presence of -a system wide installed substitute, the library's -[SONAME](https://en.wikipedia.org/wiki/Soname) is changed to enforce a hard -error if the "wrong" library is taken. Therefore it would even be possible -to deploy the self compiled libraries system wide. The SONAME can be set by -calling the Makefile like: +a system wide installed substitute, the library's [SONAME][5] is changed to +enforce a hard error if the "wrong" library is taken. Therefore it would +even be possible to deploy the self compiled libraries system wide. The +[SONAME][5] can be set by calling the Makefile like: -``` -make SONAME_SUFFIX= -make SONAME_SUFFIX=Octave64 -``` + make SONAME_SUFFIX= + make SONAME_SUFFIX=Octave64 The first call leaves the library names unchanged, while the second call adds -the suffix "\_Octave64" to each library, which is the default behavior. For +the suffix `_Octave64` to each library, which is the default behavior. For more information on shared libraries in common Linux distributions, see the subsection below. For more information on the topic of building GNU Octave using large indices, -check the -[GNU Octave manual](https://www.gnu.org/software/octave/doc/interpreter/Compiling-Octave-with-64_002dbit-Indexing.html) -or the -[GNU Octave wiki](http://wiki.octave.org/Enable_large_arrays:_Build_octave_such_that_it_can_use_arrays_larger_than_2Gb.). +see the [GNU Octave manual][3] or the [GNU Octave wiki][4]. ## Similar works -This project is greatly inspired by a -[blog post by Richard Calaba](http://calaba.tumblr.com/post/107087607479/octave-64), -who created one year ahead a -[GitHub](https://github.com/calaba/octave-3.8.2-enable-64-ubuntu-14.04) -repository for GNU Octave 3.8. +This project is greatly inspired by a [blog post by Richard Calaba][7], +who created one year ahead a [GitHub repository for GNU Octave 3.8][8]. For Windows, there is a cross-compiling solution, called [MXE-Octave](http://wiki.octave.org/MXE). It compiles all dependencies from @@ -130,32 +113,29 @@ scratch, thus requires much more disc space and time than this approach. ## Shared libraries and debugging techniques -As all of this project deals with the correct treatment of shared libraries, it -follows a short review on how to work with them and debug their usage. +As all of this project deals with the correct treatment of shared libraries, +it follows a short review on how to work with them and debug their usage. ### Environment variables A method to ensure that shared libraries located in a certain folder are found, -is to export the system environment variable **LD_LIBRARY_PATH**. In the -example below, the environment variable gets extended by the path */opt/lib*. +is to export the system environment variable `LD_LIBRARY_PATH`. In the +example below, the environment variable gets extended by the path `/opt/lib`. + + export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH + ./run-your-program -``` -export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH -./run-your-program -``` +Another **very verbose** method to figure out what shared libraries your +system is actually loading and at which paths your system is looking for them, +is exporting the system environment variable `LD_DEBUG`: -Another **very verbose** method to figure out what shared libraries your system -is actually loading and at which paths your system is looking for them, is -exporting the system environment variable **LD_DEBUG**: + export LD_DEBUG={files|bindings|libs|versions|help} + ./run-your-program -``` -export LD_DEBUG={files|bindings|libs|versions|help} -./run-your-program -``` +The meaning of the individual values of `LD_DEBUG` can be found at +[tldp.org][6]. -The meaning of the individual values of *LD_DEBUG* can be found in [1] (see -below). ### Useful tools @@ -177,17 +157,27 @@ ID `` (which can for example be found out with `pgrep -l octave`) and a shared library of interest is called ``, then the commands can be used as follows: -``` -ldd {|} -nm -D {|} -objdump {|} -readelf -d {|} -pmap -``` + ldd {|} + nm -D {|} + objdump {|} + readelf -d {|} + pmap To get a further insight into shared libraries, here are some more advanced references on this topic: -- [1] http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html -- [2] http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html -- [3] http://www.ibm.com/developerworks/library/l-dynamic-libraries +- [tldp.org][6] +- [yolinux.com][9] +- [ibm.com][10] + + +[1]: https://www.gnu.org/software/octave/ +[2]: https://www.gnu.org/software/octave/doc/interpreter/Build-Dependencies.html +[3]: https://www.gnu.org/software/octave/doc/interpreter/Compiling-Octave-with-64_002dbit-Indexing.html +[4]: http://wiki.octave.org/Enable_large_arrays:_Build_octave_such_that_it_can_use_arrays_larger_than_2Gb. +[5]: https://en.wikipedia.org/wiki/Soname +[6]: http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html +[7]: http://calaba.tumblr.com/post/107087607479/octave-64 +[8]: https://github.com/calaba/octave-3.8.2-enable-64-ubuntu-14.04 +[9]: http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html +[10]: http://www.ibm.com/developerworks/library/l-dynamic-libraries