i have a makefile for some code library i'm using and now i've added to that code some code that uses gsl. i'm not so sure how and what to add to the makefile (which i wat to keep since it's invoking boost as well) that would invoke gsl.
This is my makefile:
CXX = g++
ARCH = -mtune=generic
# ARCH = -march=core2
# ARCH = -march=native
COFLAGS = $(ARCH) -O3 -pipe
CXXFLAGS = -Wall $(COFLAGS)
PROGRAMS = getData analyzeData
BOOSTFLAGS = -I .
OPENMP = -fopenmp -DSUPPORT_OPENMP
all: $(PROGRAMS)
getData: getData.cpp common.o parse.o common.h
$(CXX) $(CXXFLAGS) getData.cpp common.o parse.o -o getData
analyzeData: analyzeData.cpp common.o parse.o parameters.o
$(CXX) $(CXXFLAGS) $(BOOSTFLAGS) $(OPENMP) estimateCrossReplicatesExpression.cpp common.o parse.o parameters.o -o analyzeData
parameters.o: parameters.cpp parameters.h
parse.o: parse.cpp parse.h
common.o: common.cpp common.h
clean:
rm *.o $(PROGRAMS)
In case GSL is installed on the default path (/usr/local/include/gsl) on your system, the compilation command for a source file "example.c" would be
gcc -Wall -I/usr/local/include -c example.c
The library is installed as a single file, libgsl.a. A shared version of the library libgsl.so is also installed on systems that support shared libraries. The default location of these files is /usr/local/lib. If this directory is not on the standard search path of your linker you will also need to provide its location as a command line flag.
To link against the library you need to specify both the main library and a supporting cblas library, which provides standard basic linear algebra subroutines. A suitable cblas implementation is provided in the library libgslcblas.a if your system does not provide one. The following example shows how to link an application with the library,
$ gcc -L/usr/local/lib example.o -lgsl -lgslcblas -lm
The option -lm links with the system math library. On some systems it is not needed.
Thus, you need to specify the gsl specific flags in your compile command. Update the Makefile accordingly.
Related
I compile with the following command:
gcc -Wall -march=native -O3 -ffast-math -I/usr/local/include -I/usr/local/include -o waon main.o notes.o midi.o analyse.o fft.o hc.o snd.o -L/usr/local/lib -L/usr/local/lib -lfftw3 -L/usr/local/lib -lsndfile -lm
I now would like to compile with Emscripten. How do I convert the above gcc command into an emcc command?
The command you have described in the question is linking rather than compiling. However in general you should just be able to replace gcc with emcc and it will do the right thing. In this case you will need to replace not only this linking command but also the commands used to compile the sources to the .o files.
It would probably be a good idea to take out the -march option.
It looks like your project is using libsndfile and FFTW. You will probably need to compile these libraries yourself using emscripten. Both of them are using autotools so with a bit of luck you can compile them with emscripten simply by adding the following parameters when you run the configure script:
./configure --prefix=$HOME/emscripten-libs CC=emcc
make && make install
Then when you link your program you can specify -L$HOME/emscripten-libs/lib instead of -L/usr/local/lib.
Make research about emsdk download&setup on your computer.
Download emsdk instruction
Next interest link is :
emcc or em++ instruction
https://emscripten.org/docs/tools_reference/emcc.html
When you setup emcc in command line you can see this project (i make emcc final look based on python script runner.py etc.):
c-cpp-to-javascript
Basic and useful example's :
Pretty analog with gcc :
Args:
-lGL for openGL
-s TOTAL_MEMORY=512MB --memory-init-file 1 Memory staff
--preload-file folderWithImages/--use-preload-plugins If you use assets
-I forInclude/someheader.h
-L libraryFolder/someLib.lib
-std=c11
Simple run:
./emcc -O2 a.cpp -o a.js
or
./emcc -O2 a.cpp -o a.html
Links:
./emcc -O2 a.cpp -o a.bc
./emcc -O2 b.cpp -o b.bc
./emcc -O2 a.bc b.bc -o project.js
Or :
to get JS
emcc -s WASM=1 myAdds.a myLib.a source1.c source2.cpp -o build.js
to get html
emcc -s WASM=1 myAdds.a myLib.a source1.c source2.cpp -o build.html
Link together the bitcode files:
emcc project.bc libstuff.bc -o allproject.bc
Compile the combined bitcode to HTML
emcc allproject.bc -o final.html
Important note :
You can't take an existing .a library and convert it. You must build lib with emcc also.
I'm following Zed Shaw's tutorial "Learn C the Hard Way" and trying to teach myself c programming language.
On my ubuntu desktop, I encountered the linking problem he mentioned in the note of this post.
That is, when linking a static library with gcc, using a command like this:
gcc -Wall -g -DNDEBUG -lmylib ex29.c -o ex29
The linker fails to find the functions in the lib. To link correctly, I have to change the order of source file and lib to this:
gcc -Wall -g -DNDEBUG ex29.c -lmylib -o ex29
And I'm trying to use the makefile offered by Zed to automate unit test. The makefile looks like this:
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/libYOUR_LIBRARY.a
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
The rest part of the makefile that isn't listed here can build the $(TARGET) lib flawlessly.
The problem is Zed append the lib to the $(CFLAGS) and use the implicit rule to compile the test files which leads to a command like this:
gcc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG tests/hashmap_tests.c build/mylib.a -o tests/list_tests
The command fails because of the link problem mentioned before as expected.
The solution I came up with was to write the compilation command explicitly like this so I can change the order:
$(TESTS): $(TARGET)
$(CC) $(CFLAGS) $^ $(TARGET) -o $#
This works fine if there is only one main source file. Unfortunately, I have several out there under the ./tests directory, and a command like this is a total disaster.
My question is, how should I change my makefile to make it work or is there any other way I can do the same work as elegant as expected?
CFLAGS holds compiler flags, like -g -O2. You should not add linker flags to it. CPPFLAGS holds preprocessor flags like -Isrc -DNDEBUG. LDFLAGS holds linker flags, which would include things like -L (capital L) if you need it to find libraries, and -rdynamic. And the LDLIBS variable holds libraries, so you should do this:
CPPFLAGS = -Isrc -DNDEBUG
CFLAGS = -g -O2 -Wall -Wextra
LDFLAGS = -rdynamic
LDLIBS = -lmylib
Now you can use the built-in rules for GNU make to build your program. You can see a list of the build-in rules by running make -p -f/dev/null.
Of course the above are just the default variables make defines and uses with its default rules. You don't have to use them, but in general it's better to follow conventions rather than flaunt them.
How does one portably find cflags and ldflags of a julia install to pass to a C compiler?
I am trying to embed Julia in a C application. Right now I can hardcode julia libraries in the compile line, but I would prefer to find a mechanism that is a bit more portable.
Here is my current Makefile which require the julia executable to be pointing into the source directory.
JULIA_BIN = $(shell dirname `which julia`)
JULIA_PATH = $(JULIA_BIN)/../..
JULIA_LIBDIR = $(JULIA_PATH)/usr/lib
JULIA_CFLAGS = -I$(JULIA_PATH)/src -I$(JULIA_PATH)/src/support I$(JULIA_PATH)/include/julia -I$(JULIA_PATH)/usr/include
JULIA_LDFLAGS = -L$(JULIA_LIBDIR) -Wl,-rpath -Wl,$(JULIA_LIBDIR) -ljulia
$(LIBTD_JULIA): td.h td_julia.c $(LIBTD)
$(CC) $(DEBUG) -fPIC -c td_julia.c -o td_julia.o $(JULIA_CFLAGS)
$(CC) $(DEBUG) -shared -fPIC td_julia.o -o $# $(JULIA_LDFLAGS) ./$(LIBTD)
I have written a makefile like the following:
COMPILER = g++
COMPILER_FLAGS = -c -g -O0 -Wall -w
EXEC=mhu9_mp3
LD = g++
LINKER = g++
mhu9_mp3 : mhu9_mp3.o teapot.o EasyBMP.o
$(LD) teapot.o mhu9_mp3.o EasyBMP.o -L./SOIL/lib -lSOIL -o mhu9_mp3 -L./usr/lib -lGL -lGLU -lglut -lGLEW
teapot.o : teapot.cpp teapot.h
$(COMPILER) $(COMPILER_FLAGS) teapot.cpp
mhu9_mp3.o : mhu9_mp3.cpp teapot.h
$(COMPILER) $(COMPILER_FLAGS) mhu9_mp3.cpp
EasyBMP.o : EasyBMP_1.06/EasyBMP.cpp
$(COMPILER) $(COMPILER_FLAGS) EasyBMP_1.06/EasyBMP.cpp
clean:
-rm -f *.o mhu9_mp3
where libSOIL.a is a static library (I linked it by using "-L./SOIL/lib -lSOIL") and -lGL -lGLU -lglut -lGLEW are dynamic libraries. I have linked them together at the same line. In my cpp file I have a function call that calls a function defined in SOIL.h . However, when I compiled I got this error:
undefined reference to `SOIL_load_image'
I'm pretty sure I have included the header file SOIL.h, and also I have linked in the static library libSOIL.a. So what is the reason for this error? I try adding a -static flag before the -lSOIL but the linker wrongly assumes other dynamics libraries are static. Is there any better ways of linking static and dynamic libraries at the same time?
Put the list of dynamic libraries before the list of static libraries.
Example:
$(LD) -L<path> -l<dynamiclib1> -l<dynamiclib2> -static -l<staticlib1> -l<staticlib2>
Counterpart of -static is -Bdynamic. So if you really have to, it could be something like
ld -o foo foo.o -static -lstaticlib -Bdynamic -ldynamiclib0 -ldynamiclib1
However, this makes sense only when both dynamic and static libraries are present. If only one exists, linker will chose one itself.
In your case, problem may be caused by wrong link order or by the fact that SOIL_load_image is indeed missing (verify it with nm or objdump).
I want to compile a shared library on MBP and based on the advise given here, I have switched to clang (from gcc) to create the shared library. My makefile is:
CC = clang
CFLAGS = -c -fPIC -Wall -O3 -lpthread -g
BaseDir = /Users/admin/Prog/
Include = -I$(BaseDir)UMFPACK/Include -I$(BaseDir)AMD/Include -I$(BaseDir)SuiteSparse_config
Lib = -L$(BaseDir)UMFPACK/Lib -L$(BaseDir)AMD/Lib -L$(BaseDir)GotoBLAS2 -L$(BaseDir)SuiteSparse_config
AddFiles = -lumfpack -lamd -lgoto2 -lsuitesparseconfig
StaticLibs = $(BaseDir)GotoBLAS2/libgoto2.a $(BaseDir)UMFPACK/Lib/libumfpack.a $(BaseDir)AMD/Lib/libamd.a $(BaseDir)SuiteSparse_config/libsuitesparseconfig.a
all: TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h
$(CC) $(Include) $(Lib) $(AddFiles) -dynamiclib -lpthread -o libTDS.so $^ -lm -g $(StaticLibs)
TDS.o: TDS.c TDS.h
$(CC) $(Include) $(CFLAGS) $^
TDSJac.o: TDSJac.c TDS.h
$(CC) $(CFLAGS) $^
ExtraRoutines.o: ExtraRoutines.c TDS.h
$(CC) $(CFLAGS) $^
CalcVFC.o: CalcVFC.c TDS.h
$(CC) $(CFLAGS) $^
MexFile: TDSGateway.c
mex -g -largeArrayDims -ldl TDSGateway.c
Move:
mv libTDS.so ../../
mv TDSGateway.mexmaci64 ../../
What I do here is:
1) Only compile TDS.c, TDSJac.c, ExtraRoutines.c, and CalcVFC.c to create four corresponding object files.
2) Merging object files and creating a shared library using following command:
clang -I(Some folders) -L(Some folders) -l(Some libraries) -shared -lpthread -o libTDS.so TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h -lm -g
clang: error: cannot specify -o when generating multiple output files
As I am absolutely new to clang, I do not know what is wrong with Makefile. (If I replace CC=clang with CC=gcc, everything works good.)
I searched the internet with no success. Manual page of clang says nothing about shared library. I could not even get anything out of clang homepage. It is appreciated if help me to work around this problem.
Thanks for your help in advance.
I had yesterday almost the same problem.
But i never used cmake. I'm using an own makefile system of my company, so I just can tell you, what fixed the problem for me so far.
Clang has still some trouble with giving you the right hints on errorcase.
The linking error was:
/usr/bin/ld: /usr/lib/crt1.o: relocation R_X86_64_32 against `_DYNAMIC' can not be used when making a shared object; recompile with -fPIC
I solved the problem as I figgered out, that the -shared Parameter has to be behind the -o X.o parameters. As I see this is not made in your case, too. You should try that first.
In our case I also had to parse the LFlags with -WL, or -L, (afaik it doesn't matter which one you take but I read about a clang bug in relation to -Wl,).
But idk in how far you have to parse LFlags or not, when using cmake.
You've listed headers (TDS.h) as dependencies, which is fine, but you've then used $^ as inputs, which includes all dependencies. You should not list a header as an input. It should not be on the command-line at all, and in clang this is actually an error.
The error message is obscure but easy to resolve. You have 2 choices:
Be explicit instead of using $^. You could use a variable for inputs and another for dependencies, e.g.; or
Use intermediate .o files instead of .c files as inputs to a .so. The *.o files can depend on any .h they include.