I am writing a C library and program using the Autotools stack. It's a pure C code base and it did compile before.
Now I get the following error during my autoreconf -v -f -i step:
Makefile.am: error: C++ source seen but 'CXX' is undefined
Just to state it again. There are no .cc or .cxx or .cpp files in the whole repository. The problem showed up when I started to add two further .c files to my library.
If I add AC_PROG_CXX to configure.ac everything works smoothly, but I don't want to introduce a C++ compiler as a dependency if its not needed.
info_TEXINFOS=foo.texi
ACLOCAL_AMFLAGS=-I m4
lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = lib/foo_vector.c \
lib/sk.c\
lib/foo_err.c\
lib/foo_list.c\
lib/foo_pair.c\
lib/foo_string.c\
lib/foo_reader.c\
lib/foo_eval.cc
libfoo_la_CFLAGS = $(BDW_GC_CFLAGS) -I#abs_srcdir#/include -Wall
libfoo_la_LIBADD = $(BDW_GC_LIBS)
# version-info provided as current[:revision[:age]]
libfoo_la_LDFLAGS = -version-info 0:0:0
include_HEADERS = include/foo.h
SUBDIRS = . tests
Related
I'm trying to build a BLAS shared library for use with ghostjat/np cannot get make to run successfully on the CBLAS source code. I performed these exact steps on an Ubuntu 20 workstation:
# create new directory
mkdir ~/blas
cd ~/blas
# fetch and extract the CBLAS source code linked from the BLAS page
wget http://www.netlib.org/blas/blast-forum/cblas.tgz
tar -xvzf cblas.tgz
#cd into the CBLAS dir
cd CBLAS
#get appropriate make file according to README:
rm Makefile.in
ln -s Makefile.LINUX Makefile.in
#then we try make
make
This results in an error because gfortran was not installed:
gfortran -O3 -c sdotsub.f
make[1]: gfortran: Command not found
make[1]: *** [Makefile:247: sdotsub.o] Error 127
make[1]: Leaving directory '/home/foo/biz/machine-learning/blas/CBLAS/src'
make: *** [Makefile:147: allprecision] Error 2
So I install gfortran
sudo apt install gfortran
# answer YES to prompts
I am then able to make most of the project, but it croaks with an error:
make[1]: Entering directory '/home/foo/biz/machine-learning/blas/CBLAS/testing'
gcc -I../include -O3 -DADD_ -c c_sblas1.c
gfortran -O3 -c c_sblat1.f
c_sblat1.f:214:48:
214 | CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
Warning: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) [-Wargument-mismatch]
c_sblat1.f:218:48:
218 | CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
Warning: Rank mismatch in argument ‘strue1’ at (1) (scalar and rank-1) [-Wargument-mismatch]
gfortran -o xscblat1 c_sblat1.o c_sblas1.o ../lib/cblas_LINUX.a libblas.a
gfortran: error: libblas.a: No such file or directory
make[1]: *** [Makefile:72: xscblat1] Error 1
make[1]: Leaving directory '/home/foo/biz/machine-learning/blas/CBLAS/testing'
make: *** [Makefile:180: alltst] Error 2
What is the problem here? This is mostly greek to me, but it looks like it compiles successfully all the CBLAS source code except it seems to barf when it gets to the testing, complaining that it cannot find a file, libblas.a. Can someone help me make sure this make operation completes?
Also, I was expecting this compilation step to produce a shared library, perhaps cblas.so or something. I am hoping this process will yield a viable BLAS library that I can use with ghostjat/np to perform fast matrix operations from a PHP script. However, there are no files in this directory ending in .so. Should I be looking for some other file?
EDIT: the comments have suggested that perhaps I should 'install BLAS' or 'install the libopenblas-dev package' on this machine. Let me first say that my goal is to obtain a library that I might distribute with some PHP source code. I am under the impression that building/making CBLAS will provide this library.
EDIT 2: After attempting a lot of trial and error, I think (but am not sure) that CBLAS is not a full-blown implementation of the BLAS functionality, but just a C wrapper around the BLAS functions, which are written in FORTRAN. It would appear that the makefile in CBLAS must be changed to point to a BLAS static library. I've been able to build the BLAS 3.11.0 library like so:
cd ~/blas
curl https://netlib.org/blas/blas-3.11.0.tgz > blas-3.11.0.tgz
tar -xvzf blas-3.11.0.tgz
cd BLAS-3.11.0
make
this runs for about a minute or so and yields a static lib, blas_LINUX.a. I take note of this file's location:
/Users/foo/Desktop/biz/machine-learning/blas2/BLAS-3.11.0/blas_LINUX.a.
I then return to my previously downloaded/extracted CBLAS folder:
cd ~/blas/CBLAS
and note this information in the README file:
BLLIB is your Legacy BLAS library
I edit this line in Makefile.in:
BLLIB = libblas.a
so that it refers instead to the static blas_LINUX. I just compiled above:
BLLIB = /Users/foo/Desktop/biz/machine-learning/blas2/BLAS-3.11.0/blas_LINUX.a
I save the make file and then make CBLAS:
make clean all
This runs for awhile, but fails in the testing phase with a certain gfortrain complaint:
( cd testing && make all )
gcc -I../include -O3 -DADD_ -c c_sblas1.c
gfortran -O3 -c c_sblat1.f
c_sblat1.f:214:48:
214 | CALL STEST1(SNRM2TEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
Error: Rank mismatch in argument 'strue1' at (1) (scalar and rank-1)
c_sblat1.f:218:48:
218 | CALL STEST1(SASUMTEST(N,SX,INCX),STEMP,STEMP,SFAC)
| 1
Error: Rank mismatch in argument 'strue1' at (1) (scalar and rank-1)
make[1]: *** [c_sblat1.o] Error 1
make: *** [alltst] Error 2
Not a direct answer, but since you're on Ubuntu you can just install the libopenblas-dev package which contains the cblas headers and will pull in a high performance BLAS library as a dependency.
I stumbled across these directions which have worked for me, at least on Ubuntu 20.04. A couple of things changed so I list the exact steps I took here on my Ubuntu 20.04 workstation. The basic solution is to first compile BLAS (this appears to be FORTRAIN code) into a static library, blas_LINUX.a, and then modify the CBLAS files to point to that static library. There are tgz archives for both on the BLAS homepage.
# make a working dir
mkdir ~/cblas
cd ~/cblas
# fetch the BLAS library (not CBLAS, just BLA)S
wget http://www.netlib.org/blas/blas-3.11.0.tgz
tar -xvzf blas-3.11.0.tgz
cd BLAS-3.11.0
make
This will produce a file, blas_LINUX.a. Take note of its location here, you'll need to refer to it in the CBLAS make file. Next, fetch CBLAS and compile.
# get out of this directory back to our working dir
cd ..
# fetch CBLAS tgz, linked from netlib page
wget http://www.netlib.org/blas/blast-forum/cblas.tgz
# extract it
tar -cvzf cblas.tgz
# cd into CBLAS dir for edits
cd CBLAS
# remove default makefile
rm Makefile.in
# copy LINUX make file to Makefile.in
ln -s Makefile.LINUX Makefile.in
# edit Makefile.in
nano Makefile.in
Make the following changes:
# path to just-compiled static lib
# NOTE your path will be different
BLLIB = /home/sneakyimp/cblas/BLAS-3.11.0/blas_LINUX.a
CBLIB = ../lib/cblas_$(PLAT).so
CFLAGS = -O3 -DADD_ -fPIC
FFLAGS = -O3 -fPIC
ARCH = gcc
ARCHFLAGS = -shared -o
Save & close Makefile.in and then make CBLAS
# this takes a bit of time
make
# ls -al lib
You should now have your so file in lib/cblas_LINUX.so
I was able edit the blas.h file in a composer-installed ghostjat/np to point to this cblas_LINUX.so file, and eventually get it working, but you'll have complaints about various functions in the that blas.h file which are not defined in CBLAS. If you remove each of the functions it complains about you may get it to work or not. I was able to get it working on Ubuntu 20 running php 8.2, but have had trouble on other machines. My attempt to run cblas_dgemm on a matrix i defined resulted in this error:
php: symbol lookup error: /home/sneakyimp/cblas/CBLAS/lib/cblas_LINUX.so: undefined symbol: dgemm_
I am trying to compile a library with autotools. The library compiles fine with the following Makefile.am in its source directory library/src
lib_LTLIBRARIES = libgtkchart.la
libgtkchart_la_CFLAGS = $(CFLAGS) -fPIC -Wall $(gtk_CFLAGS)
libgtkchart_la_LIBADD = $(gtk_LIBS) $(glib_LIBS)
libgtkchart_la_LDFLAGS = -fPIC -shared -version-info 1:0:0
libgtkchart_la_SOURCES = gtkchart.c gtkaxis.c gtkbarchart.c gtkchartdata.c gtkchart.h gtkaxis.h gtkbarchart.h gtkbarchartdata.h
but if I add the following line to that file:
include_HEADERS = gtkaxis.h gtkbarchart.h gtkbarchartdata.h gtkchart.h
I get the following error:
make[2]: *** No rule to make target 'gtkbarchartdata.h', needed by 'all-am'. Stop.
My main MAkefile.am in library/ is
SUBDIRS = src
ACLOCAL_AMFLAGS= -I m4
and my configure.ac is
AC_CONFIG_MACRO_DIRS([m4])
AC_INIT([library], [1.0], [me])
AM_PROG_AR
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
LT_INIT
AC_OUTPUT
I can't figure out why the need for a target for that header file.
When you assign header files to the include_HEADERS, automake must
be able to locate the header.
For example, if you have the following directory structure:
src
Makefile.am
GTKBarCharDataDirectory
SomeOtherDirectory
gtkaxis.h
gtkbarchart.h
gtkchart.h
And gtkbarchartdata.h is located in the GTKBarCharDataDirectory directory, then you need to change your include_Headers to be:
include_HEADERS = gtkaxis.h gtkbarchart.h GTKBarCharDataDirectory/gtkbarchartdata.h gtkchart.h
make must know the relative path of the header file, when using the include_Headers variable. This is due to the fact that the HEADER family of variables works differently than the SOURCES family of variables.
automake won't fail if you list a non-existent/not-found header file
in the libgtkchart_la_SOURCES variable, since Header files listed in
a _SOURCES definition will be included in the distribution but
otherwise ignored.
Check here and here for a reference
I'm trying to simulate "gcc -c program.c -o program.o" in automake Makefile.am to then be used in a shared library.
I have something like
lib_LTLIBRARIES = libsomething.la
libsomething_la_CPPFLAGS = -I/dir/
include_Headers = dir/neededHeader.h
libsomething_la_SOURCES = src/program.c
But this seems to go farther than the just creating a .o file and putting it in the library. The reason I'm trying to do this is I have c functions but do not give prototypes for them. They are declared externally in another file that links to the library trying to be created. Which if given prototypes in both locations would cause an error. I can do this from terminal commands and with making my own custom Makefile but want the portability of using automake.
I have about 39 Fortran F90 source files and 35 Fortran 77 Lapack related files. I am using include statement in my main program to connect all these files.
I have created a batch file make.bat with command ifort "MDL HydroD.F90" which compiles my code and generates the mdlhydrod.exe file. In the process the Fortran compiler creates many .mod and .obj build files which makes it difficult to manage. I would like to put my source files under a directory Source and lapack library files in a directory lapack and build files in a directory Debug.
Could anyone help me modify my make.bat file so that ifort looks at Source directory and build in Debug directory.
Thank you for help.
Currently using make.bat has only one line of command:
File Name: make.bat
ifort "MDL HydroD.F90"
Working on a make file to be used with nmake (incomplete):
File Name: make.mak:
#Make File for MDL HydroD
# Compiler options
FC := ifort
VPATH := src
BINDIR := bin
$(BINDIR):
mkdir -p $(BINDIR)
clean:
#rm -rf $(BINDIR)
Because you are using a strange way of working with source files, which you showed in your other question, it will be very difficult to change this.
For recapitulation, you include everything in a single source file using the include statement. This looks pretty unfortunate to me and I commented on that there. If you have one source file, you are forced to build it with one command, there is no place for any fine control. This is not the issue of a bash or bat script vs. Makefile.
You can probably still keep some files included in some groups that are logically similar, if you need no finer control on that, but I see not much reason for that.
Remove the includes or at least the relevant ones. Then you can just do
ifort Source/the_source_file1 -c Output/name_of_obj1 -module the_directory_for_modules -I the_directory_for_modules -other_flags
for every file. And then in the end:
ifort Output/name_of_obj1 Output/name_of_obj2 Output/name_of_obj3 .... -o the_result
In Scons (which I would use) it would be like this (tested on couple of dummy files). The file Sconstruct:
import os
env = Environment(tools=['default','ifort'])
env.Append(ENV = {'PATH' : os.environ['PATH']})
try:
env.Append(ENV = {'LIBRARY_PATH' : os.environ['LIBRARY_PATH']})
except:
pass
env.Append(F90FLAGS='-g -fast') #whatever flags you need
env.Append(FORTRANFLAGS='-g -fast') #whatever flags you need
outdir = "Output/"
srcdir = "Sources/"
lapackdir = "lapack/"
objs = []
for file in os.listdir(srcdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=srcdir+file)
for file in os.listdir(lapackdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=lapackdir+file)
env.Append(FORTRANMODDIR = outdir)
objs = filter(lambda o: str(o)[-4:] != '.mod', objs)
prg = env.Program(target="bin/result.exe", source= objs)
Default(prg)
I'm new to autotools and I've been searching for an example of how to package up a library and an executable using autotools. The executable depends on the library so the library will have to be built first.
So far I've got the library packaged up on it's own, and then I've been able to compile the executable and link to the library once that is installed. Here is my Makefile.am for that process:
lib_LTLIBRARIES = libfoo.1.0.0.la
libfoo_1_0_0_la_SOURCES = libfoo.c
library_includedir=$(includedir)
library_include_HEADERS = libfoo.h
Then in the configure.ac file I added the line LT_INIT in the appropriate place. Everything builds nicely and works. I have a file foo.c that uses the library that I can compile with gcc foo.c -o foo -lfoo, however I'd like to extend the autotools package to include the foo executable, I can't work out how to do this. I've modified the Makefile.am to look like this:
bin_PROGRAMS=foo
foo_SOURCES=foo.c
foo_DEPENDENCIES=libfoo.1.0.0.la
lib_LTLIBRARIES = libfoo.1.0.0.la
libfoo_1_0_0_la_SOURCES = libfoo.c
library_includedir=$(includedir)
library_include_HEADERS = libfoo.h
My configure.ac file is unchanged. Everything runs fine until I get to make, at this point it seems that foo.c is compiled first and obviously throws lots of errors as the functions in libfoo aren't available. I've searched for an example like this but so far not had any luck. Any help would be appreciated.
This is the proper way to do it.
lib_LTLIBRARIES = libmoovcaps.la
libmovcaps_la_SOURCES = libmoovcaps.c
include_HEADERS = libmoovcaps.h
bin_PROGRAMS = moovcaps
moovcaps_SOURCES = moovcaps.c
moovcaps_LDADD = libmoovcaps.la
P.S.: Why do you have numbers in your libmoovcaps.la? You can pass the -version-info flag via libmoovcaps_LDFLAGS.
I figured it out, I put this in my Makefile.am:
lib_LTLIBRARIES = libfoo.1.0.0.la
libfoo_la_SOURCES = libfoo.c
library_includedir=$(includedir)
library_include_HEADERS = libfoo.h
bin_PROGRAMS=foo
foo_SOURCES=foo.c
foo_DEPENDENCIES=libfoo.1.0.0.la
foo_LDADD= libfoo.o
This seems to work now :)