I am trying to compile an OpenCL project under Eclipse using Cygwin Gcc/G++ compiler and i got some Undefined References for OpenCL API functions. I saw many threads about this problem, I tried the suggested solutions but I still have these errors.
Basically my code just retrieves OpenCL infos about the platform and device I use so I dont give it here but I can if you want (even if I dont think it is very interesting).
Here is my makefile :
RM := rm -rf
OpenCLEnvInfos.o: ../OpenCLEnvInfos.cpp
g++ -IINCLUDE_DIR1 -IINCLUDE_DIR2 -g3 -Wall -c ../OpenCLEnvInfos.cpp -o OpenCLEnvInfos.o
#echo ' '
OpenCL_infos.o: ../OpenCL_infos.cpp
g++ -IINCLUDE_DIR1 -IINCLUDE_DIR2 -g3 -Wall -c ../OpenCL_infos.cpp -o OpenCL_infos.o
#echo ' '
# All Target
all: OpenCLEnvInfos.exe
# Tool invocations
OpenCLEnvInfos.exe: OpenCLEnvInfos.o OpenCL_infos.o
g++ -o OpenCLEnvInfos.exe OpenCLEnvInfos.o OpenCL_infos.o -LOpenCL -LGAL-fb
#echo ' '
# Other Targets
clean:
-$(RM) OpenCLEnvInfos.o OpenCL_infos.o OpenCLEnvInfos.d OpenCL_infos.d OpenCLEnvInfos.exe
#echo ' '
I tried everything (Libs order in linking command), -l instead of -L (but the compiler doesnt find them) ... Eclipse makefile generation make more errors occurs that's why I had to rewrite it...
I hope someone has the answer :p
Baptiste
You misuse compiler switches. Read the GCC manual for more information.
With -L you should provide the path to the directory where to search for libraries. In your case, where libOpenCL.a or OpenCL.a are located. For example:
-LD:/Libraries/OpenCL/lib
With -l you specify the library you want to link against. In your case, that would be libOpenCL.a or OpenCL.a. Like this:
-lOpenCL
The order is correct. In other words, you should keep these -l switches after all *.o files (in the invocation of g++ for linkage stage) if these *.o files depend on the libraries specified by -l, what in your case is indeed true.
Related
I have the following C++ code in a file called helloworld.cpp:
#include<iostream>
int main()
{
std::cout << "Hello, World!\n";
}
I would like to compile this manually so I can really understand how the compilation steps work with gcc, namely:
Preprocessing
Compilation
Assembly
Linking
This article gives some useful information about how to break up the compilation steps. And so I came up with the following:
Preprocessing
cpp helloworld.cpp > helloworld.i
Compilation
g++ -S helloworld.i
Assembly as -o helloworld.o helloworld.s
Linking
ld -o helloworld helloworld.o
Everything seems to work except for the last step, as outlined by the article:
ld -o hello hello.o ...libraries...
The libraries argument above is a long list of libraries that you need to find out. I omitted the exact arguments because the list is really long and complicated, and depends on which libraries g++ is using on your system. If you are interested to find out, you can run the command g++ -Q -v -o hello hello.cpp and take a look at the last line where g++ invokes collect2
And so I tried running g++ -Q -v -o helloworld helloworld.cpp, but the result is extremely verbose.
I'm still unsure how to complete ld such that iostream can be available to the linker when I invoke it. How can I make sure iostream is available to the linker?
I'm still unsure how to complete ld such that iostream can be available to the linker when I invoke it.
You should never use ld to link any user-level programs, only when you are linking something esoteric, like an OS kernel or a boot loader.
Instead, (for user-level program) always use appropriate compiler driver (g++ here).
While you can find out how the compiler driver eventually invokes ld internally (e.g. using strace -fe execve -s 1024 g++ ...), note that that command may change from version to version, and depends on a multitude of flags (-pie vs. -no-pie, -shared, -static etc.) and you chances of continuing to use correct ld command after a few months are nil.
Based on the comments and posted answer I realized that the blog from which I was copying those commands makes things more complicated than they really need to be for my purposes. It's definitely possible to isolate every step of the compilation process using solely the g++ command. Here's a Makefile I came up with:
all: preprocess compile assemble link
# helloworld.i contains preprocessed source code
preprocess:
#echo "\nPREPROCESSING\n"; g++ -E -o helloworld.i helloworld.cpp
# compile preprocessed source code to assembly language.
# hello.s will contain assembly code
compile:
#echo "\nCOMPILATION\n"; g++ -S helloworld.i
# convert assembly to machine code
assemble:
#echo "\nASSEMBLY\n"; g++ -c helloworld.s
# links object code with the library code to produce an executable
# libraries need to be specified here
link:
#echo "\nLINKING\n"; g++ helloworld.o -o test
clean:
#find -type f ! -name "*.cpp" ! -name "*.h" ! -name "Makefile" -delete
Now I can compile my C++ programs in such a way that I can track whether the preprocessor, compiler, assembler or linker is generating the error.
I am new to C++ and I am having trouble understanding how Makefiles do their thing with the g++ compiler.
I have successfully installed armadillo library (via apt) and have a very simple c++ program test.cpp, like the one below:
#include <iostream>
#include <armadillo>
using namespace std;
int main()
{
arma::mat A;
A << -1 << 2 << arma::endr
<< 3 << 5;
cout << A << endl;
arma::fmat B;
B.randu(4,5);
cout << B;
return 0;
}
This works just fine if I compile manually like this:
g++ src/test.cpp -std=c++11 -Wall -o test -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
I can manually run the program and it delivers the matrices as expected.
On the other hand, I have the Makefile template from the VSCode C/C++ Extension, which I have modifed slightly for including the LAPACK an BLAS Fortran libraries:
########################################################################
####################### Makefile Template ##############################
########################################################################
# Compiler settings - Can be customized.
CC = g++
CXXFLAGS = -std=c++11 -Wall
LDFLAGS = -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
# Makefile settings - Can be customized.
APPNAME = test
EXT = .cpp
SRCDIR = src
OBJDIR = obj
############## Do not change anything from here downwards! #############
SRC = $(wildcard $(SRCDIR)/*$(EXT))
OBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP = $(OBJ:$(OBJDIR)/%.o=%.d)
# UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)
########################################################################
####################### Targets beginning here #########################
########################################################################
all: $(APPNAME)
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
# Creates the dependecy rules
%.d: $(SRCDIR)/%$(EXT)
#$(CPP) $(CFLAGS) $< -MM -MT $(#:%.d=$(OBJDIR)/%.o) >$#
# Includes all .h files
-include $(DEP)
# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $<
################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
$(RM) $(DELOBJ) $(DEP) $(APPNAME)
# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
$(RM) $(DEP)
#################### Cleaning rules for Windows OS #####################
# Cleans complete project
.PHONY: cleanw
cleanw:
$(DEL) $(WDELOBJ) $(DEP) $(APPNAME)$(EXE)
# Cleans only all files with the extension .d
.PHONY: cleandepw
cleandepw:
$(DEL) $(DEP)
I have passed the needed libraries under LDFLAGS = -DARMA_DONT_USE_WRAPPER -lopenblas -llapack. Nevertheless, this solution does not work. It looks to me like the compiler is unable to find the armadillo library, so I must have linked it somehow wrongly. It delivers:
g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
/usr/bin/ld: obj/test.o: in function `TLS wrapper function for arma::arma_rng_cxx11_instance':
test.cpp:(.text._ZTWN4arma23arma_rng_cxx11_instanceE[_ZTWN4arma23arma_rng_cxx11_instanceE]+0x25): undefined reference to `arma::arma_rng_cxx11_instance'
collect2: error: ld returned 1 exit status
make: *** [Makefile:36: test] Error 1
So, aside from the obvious question (Why does this not work?), I would as well appreciate if someone could help me clarify as well the following aspects:
On the one hand, rom the message error it seems that the command run g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack does not include the name of the cpp file I wrote (as opposed to in my manual compilation, in which it works). Nevertheless, if I do not use armadillo, the Makefile recipe above works just fine. I see the Makefile somehow looking for all cpp files in the source code folder SRC = $(wildcard $(SRCDIR)/*$(EXT)), but I cannot see where is this forwarded to the compiler. Can someone help me with that?
The other thing is that, in my manual compilation, it seems to make no difference to pass the LAPACK and BLAS libraries as CXXFLAGS or LDFLAGS, meaning both of the following commands:
g++ src/test.cpp -std=c++11 -Wall -DARMA_DONT_USE_WRAPPER -lopenblas -llapack -o test
and
g++ src/test.cpp -std=c++11 -Wall -o test -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
work just fine. As far as I have been able to read, I understood the flags before -o are meant for the compiler, and those after are meant for the "linker" (whatever that is). Can someone explain me what are the main differences between the CXXFLAGS and LDFLAGS? Why both combinations work? And what is the linker?
Thank you very much for your help.
Best,
D.
The other answer is a good general introduction to compilation but if you want to know what is happening in your situation you need to first understand that answer and the difference between source files, object files, and executable files and the way that they work, then go deeper to figure out what's wrong.
As far as I have been able to read, I understood the flags before -o are meant for the compiler, and those after are meant for the "linker" (whatever that is)
No, that is not right.
Turning source files into an executable involves several steps each managed by a different tool. The compiler front-end (e.g., g++) manages the order of these. Each of these may use different options, and whenever the compiler front-end invokes one of these tools it will pass the appropriate flags from the command line for that tool. It's not the case that "only" flags before or after -o are passed to different tools; it doesn't matter where on the command line they live.
The tools involved with compilation, in the order in which they're invoked, are:
Preprocessor: this handles #include and #ifdef and #define, etc. (the lines that start with # in your source). The preprocessor takes the options -D, -I, and some others.
Compiler: this turns your source code (after preprocessing to handle all the included files etc.) into assembly code which is very low-level: basically machine code but in ASCII form. This does the bulk of the work including optimization etc. Flags like -O2, -g, and many others are used by this tool.
Assembler: this turns the assembly code into a binary format for your CPU and generates an object file (foo.o).
Linker: this takes one or more object files plus libraries and turns them into an executable. This tool uses options like -L and -l to find libraries.
There's a separate tool, the archiver (ar) which is not invoked by the compiler front-end, which is used to turn object files (foo.o) into static libraries (libfoo.a).
Note, the above is a "classical" view of building: newer compilers munge the above steps together sometimes to get either better error messages or better optimization or both.
Most of the time the first three steps are all done by a single invocation of the compiler front-end: it turns a source file into an object file. You do this once for each source file. Then at the end, another invocation of the compiler front-end takes those object files and builds an executable.
If you look at the output make prints you'll see these two steps. First you'll see the compilation step, which is controlled by this make rule:
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $<
and runs this command:
g++ -std=c++11 -Wall -o obj/test.o -c src/test.cpp
The -c option here tells the compiler, "do all the steps up to and including the compile step, then stop and don't do the link step".
Then you will see your link command, which is controlled by this make rule:
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
and runs this command:
g++ -std=c++11 -Wall -o test obj/test.o -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
What do you notice about this? The -DARMA_DONT_USE_WRAPPER is a preprocessor option, but you're passing it to the link step and not passing it to the compile step. That means when the source is compiled, that option is not present and so whatever operation it was intended to suppress (using a wrapper apparently) is not being suppressed.
You need to put preprocessor options in a make variable that is sent to the compiler / preprocessor, so it should be this:
CXXFLAGS = -std=c++11 -Wall -DARMA_DONT_USE_WRAPPER
LDFLAGS = -lopenblas -llapack
Be sure to run clean before trying to build again.
One minor thing, but generally you should use CXX for your C++ compiler and CC for your C compiler (these are the usual conventions). If you do end up trying to compile C++ source with a C compiler you are likely to have problems. Less so the other way round.
So what it happening? Roughly speaking, you have two steps:
Compilation
Linking
When you compile a small exe, you can combine these into a single steps. Makefiles generally don't as two steps is more general.
For compilation the input has a .cpp suffix and you are passing the -c flag to tell the compiler to just compile. This will result in an object file (.o suffix).
For linking, there is no -c. The inputs are object files and the output is your application.
Other suffixes are possible (.cxx, .CC etc.).
There are 4 commonly used make variables
CPPFLAGS for preprocessor flags, can be used for C and C++ compilation
CFLAGS for flags specific to C compilation
CXXFLAGS for flags specific to C++ compilation
LDFLAGS for flags specific to linking
Historically, ld was the linker (and hence LDFLAGS), but it isn't smart enough to handle C++ linking well on its own. So now it is usually the C++ compiler that performs the task of "linker driver", that is g++ controls the linking that ld does.
Finally, your specific problem. You should add the armadillo library to LDFLAGS. The best way to do that is to just add -larmadillo. If armadillo is not installed in a 'standard' location like /usr/lib then you may need to additional arguments such as
-L/path//to/armadillo_lib -Wl,-rpath,/path//to/armadillo_lib
(the first one tells the linker where the library is, the second one puts that path into the executable so that is also knows where the library is).
I'm trying to create an executable that uses my earlier created shared library, which by the way is now static which includes the openSSL static library. So I used the same Makefile that I was using to create that library, and hacked it to make it work here. This is how it looks
LIBBASE=/home/AB/Documents/APP/APP_2.17.0
OPENSSL1.0.2p_INSTALL_LOC=/home/AB/Documents/APP/OpenSSL-1.0.2p-installation
CC=gcc
CXX=g++
CFLAGS= -Wall -g -pedantic
CPPFLAGS= -Wall -g -pedantic
RM= rm -f
.PHONY: all clean
c_src=$(shell find . -iname "*.c")
$(info source=$(c_src))
cpp_src=$(shell find . -iname "*.cpp")
$(info cppsource=$(cpp_src))
INC=-I$(LIBBASE)/include
$(info includes=$(INC))
# need to link pthread library here as well
LIB = -pthread
# aforementioned library
LIB+=-L$(LIBBASE)/lib
LIB+= -l:libSCA.a
#need to add SSL related libraries
LIB+= -L$(OPENSSL1.0.2p_INSTALL_LOC)/lib
LIB+= -l:libssl.a -l:libcrypto.a -static-libgcc
# As mentioned, we need to link dl and libz libraries as well
LIB+= -ldl -lz
$(info links=$(LIB))
obj=$(c_src:.c=.o) $(cpp_src:.cpp=.o)
all: APP
clean:
$(RM) *.o APP
$(shell find $(APPBASE) -type f -iname "*.o" -exec rm -rf {} \;)
.c.o:
${CXX} -static ${CPPFLAGS} $(INC) -c $< -o $#
#${CC} -static ${CFLAGS} $(INC) -c $< -o $#
.cpp.o:
${CXX} -static ${CPPFLAGS} $(INC) -c $< -o $#
APP: $(obj)
$(LINK.cxx) $^ -o $# $(LIB)
I am, however unable to get this to work. I am getting a whole lot of undefined references to symbols that my library defines. I've taken care of using extern C around those symbols in the cpp files but it doesn't seem to help.
BTW, Is there a more straightforward or easier way than this?
Also, while browsing through the various answers here, I came across the statement that, targets like .c.o are rather obsolete and shouldn't be used anymore. Is there a definitive guide to Makefiles that is recent, exhaustive and practical (is it too much to ask)??
UPDATE 1: So here that I have access to the logs, I've noticed that all the undefined reference errors I am getting are related to symbols defined by the SSL library that I was statically linking to my shared library. A sample of my err log:
/home/AB/Documents/APP/APP_2.17.0_Linux/libAPP.so: undefined reference to `SSL_CTX_free'
/home/AB/Documents/APP/APP_2.17.0_Linux/libAPP.so: undefined reference to `X509_set_issuer_name'
So I thought of making a static library that will internally link against (or rather incorporate) libssl.a. Modified my aforementioned makefile and created a static libAPP.a. But I still kept getting those errors.
I finally added libssl.a and libcrypto.a to this makefile and voila, a lot of those errors got fixed. I still had some errors related to dlopen and pthreads so I added those as well. I also compile everything with the CXX compiler to eliminate issues due to name mangling.
What bugs me now is that the SSL related symbols are supposed to be already present in libAPP.a (although nm reports them as undefined and which might need another question on it's own :D ). But I still need to specify the libSSL.a and libcrypto.a here for the linker to find them! So what good is creating an archive (libAPP.a) instead of a shared library (libAPP.so)?
Finally during the linking phase, my linker cannot find lz
/usr/bin/ld: cannot find -lz
Just for the heck of it, I tried adding the same flag into the makefile that creates that archive and that one has no problem finding it. Any suggestions??
I would do this in these steps:
Collect all commands to build everything "by hand." Only if that works it makes sense to move on if you're a beginner. These commands could be put in a batch file.
Extract the dependencies and rules.
Write that in the Makefile; at the end of the day a Makefile is just that: condensed knowledge how to build.
Try the Makefile.
If I experience errors, I'll use make's options -d, -p and -n to see what it's thinking. There might be more useful options.
Most obvious problem is that you are using $(LINK.c) to link when your program contains C++ components, so you aren't getting any C++ libraries or such. Try using $(LINK.C) or $(LINK.cc) or $(LINK.cpp) or $(LINK.cxx) (which you need for C++ varies on make version, but at least one of them should be predefined.)
I had been working on a project that uses different sources and codes from many authors (in physics) and I want to merge them together and communicate between them.
The problem is that some of those sources and makefiles call first the linked libraries and then the c files:
$(CC) $(lflags) -o smith2demo smith2demo.o smith2.o
Until now on my institute's computer and in some other systems everything was working fine. There I have this gcc compiler:
$gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
So, I had not noticed this problem until I tried to run my code on Ubuntu:
gcc (Ubuntu 4.9.3-5ubuntu1) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
In ubuntu I get things like:
smith2.c:(.text+0x29b): undefined reference to `sincos'
I am aware of the linked libraries specifications and the reason for this, answered here:
GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'
Why does the order in which libraries are linked sometimes cause errors in GCC?
Why am I getting a gcc "undefined reference" error trying to create shared objects?
So, I have two questions:
Why if both gcc's are of recent versions, I do not have this problem in the Debian system?
How can I do to distribute this code to other people, without me telling them to change all makefiles where the libraries are called before the C files?
In most of the cases within my project, I use an overall Makefile and then I just change to the source folder and perform $(MAKE) in there.
Is there a way to set the --no-as-needed in general as an option for everyone or a more intelligent way of doing this?
I have very little experience with makefiles.
In my personal life, I use my own Makefile. Here is the simpler version of it.
MAIN = main
HEADER_DEFINITIONS = fibo
CC = g++-4.9 -std=c++11
COMPILE = -c
EXE = $(MAIN)
OPTIMIZE = -Os
SHELL = /bin/bash
ARGS = 20
all: link
#echo "Executing..........."
#echo " > > > > > > OUTPUT < < < < < < "
#$(SHELL) -c './$(EXE) $(ARGS)'
link: compile
#echo -n "Linking............."
#$(SHELL) -c '$(CC) -o $(EXE) *.o'
compile: $(MAIN).cpp $(HEADER_DEFINITIONS).cpp
#echo -n "Compiling........."
#$(SHELL) -c '$(CC) $(OPTIMIZE) $(COMPILE) $^'
clean:
#echo "Cleaning............"
#$(SHELL) -c 'rm -f *~ *.o $(EXE)'
If you want to further modify and add certain linker flags, it is completely possible
Edit 2 My personal Makefile
#
# A simple makefile for managing build of project composed of C source files.
#
# It is likely that default C compiler is already gcc, but explicitly
# set, just to be sure
CC = gcc
# The CFLAGS variable sets compile flags for gcc:
# -g compile with debug information
# -Wall give verbose compiler warnings
# -O0 do not optimize generated code
# -std=c99 use the C99 standard language definition
# -m32 CS107 targets architecture IA32 (32-bit)
CFLAGS = -g -Wall -O0 -std=c99 -m32
# The LDFLAGS variable sets flags for linker
# -lm says to link in libm (the math library)
LDFLAGS = -lm
# In this section, you list the files that are part of the project.
# If you add/change names of source files, here is where you
# edit the Makefile.
SOURCES = demo.c vector.c map.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = demo
# The first target defined in the makefile is the one
# used when make is invoked with no argument. Given the definitions
# above, this Makefile file will build the one named TARGET and
# assume that it depends on all the named OBJECTS files.
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
.PHONY: clean
clean:
#rm -f $(TARGET) $(OBJECTS) core
I am attempting to install twitcurl on OS X and have met with some problems.
At first, running make would return the clang error: ld: unknown option: -soname. I looked through the responses from other users with similar problems on OS X and found the following advice:
In the makefile, change:
LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
to:
LDFLAGS += -rpath=$(STAGING_DIR)/usr/lib
change:
$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 $(LDFLAGS) -o lib$(LIBNAME).so.1.0 .o -L$(LIBRARY_DIR) -lcurl
to:
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib .o -L$(LIBRARY_DIR) -lcurl
I tried this, but the only result was another clang error: clang: error: unknown argument: '-rpath=/usr/lib'
Any advice towards installing twitcurl on an OS X system will be greatly appreciated.
----UPDATE----
I just wanted to put in one place all the steps I took to make this work, in case any OS X users with similar problems come across this in the future. My thanks to Andy Piper for the crucial pieces.
open the makefile and replace:
LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib
with:
LDFLAGS += -rpath $(STAGING_DIR)/usr/lib
and:
$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 $(LDFLAGS) -o lib$(LIBNAME).so.1.0 .o -L$(LIBRARY_DIR) -lcurl
with:
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib *.o -L$(LIBRARY_DIR) -lcurl
(note that this is different by two characters from the advice another OS X user gave above)
after running make, copy libtwitcurl.dylib into /usr/lib/
Downloading the twitterClient (which is also the only code example I could find) will be the same, but for compiling it or your own programs you will need to link -lcurl as well. (g++ appname.cpp -ltwitcurl -lcurl)
Finally, once you compile a program, the path name will likely be incorrect in the executable which is created. Use install_name_tool to correct it. For me this looks like:
install_name_tool -change libtwitcurl.dylib.1 /usr/lib/libtwitcurl.dylib nameofexecutable
but if that doesn't work for you, use otool to find the actual path:
otool -L nameofexecutable
and then the first argument after -change should be the erroneous path for libtwitcurl. You can use otool again after running install_name_tool to be sure the change was successful.
I can get the shared / dynamic library to compile but needed to make a couple of adjustments to your Makefile:
LDFLAGS += -rpath $(STAGING_DIR)/usr/lib
and
$(CC) -dynamiclib -shared -Wl,-install_name,lib$(LIBNAME).dylib.1 $(LDFLAGS) -o lib$(LIBNAME).dylib *.o -L$(LIBRARY_DIR) -lcurl
I've now also built the associated twitterClient utility. To do so, I had to symbolically link libtwitcurl.dylib as libtwitcurl.dylib.1 and also change the consumer key and secret in the code to match a valid one from apps.twitter.com on my account. Works fine.
I assume you want to use the twitcurl library from code? Twitter maintains a Ruby-based utility, twurl, which has a similar function and may also be useful.