C++ compilation error when using c++ 11 on Mac - c++11

I was using C++11 to build my project on Mac.
My make file is like:
# -lpcrecpp
#
CXX=g++
CXXFLAGS = -std=c++11 -stdlib=libstdc++ -Wall -pedantic -I.
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin
$(BIN_DIR)/test: | $(BIN_DIR) $(OBJ_DIR) $(SRC_DIR)/main.cpp $(OBJ_DIR)/recognizer.o $(OBJ_DIR)/util.o
$(CXX) $(CXXFLAGS) $(SRC_DIR)/main.cpp -lpcrecpp -o $(BIN_DIR)/test $(OBJ_DIR)/util.o $(OBJ_DIR)/recognizer.o
$(BIN_DIR):
mkdir -p $(BIN_DIR)
$(OBJ_DIR):
mkdir -p $(OBJ_DIR)
$(OBJ_DIR)/recognizer.o: $(SRC_DIR)/recognizer.cpp $(INC_DIR)/recognizer.h
$(CXX) $(CXXFLAGS) -c $(SRC_DIR)/recognizer.cpp -o $(OBJ_DIR)/recognizer.o
$(OBJ_DIR)/util.o: $(SRC_DIR)/util.cpp $(INC_DIR)/util.h
$(CXX) $(CXXFLAGS) -c $(SRC_DIR)/util.cpp -o $(OBJ_DIR)/util.o
clean:
rm -rf $(OBJ_DIR)
rm -rf $(BIN_DIR)
and I got this weird error:
g++ -std=c++11 -stdlib=libstdc++ -Wall -pedantic -I. src/main.cpp -lpcrecpp -o bin/test obj/util.o obj/recognizer.o
In file included from src/main.cpp:15:
In file included from src/../include/util.h:18:
src/../include/parameters.h:32:10: fatal error: 'unordered_map' file not found
#include <unordered_map>
^
1 error generated.
WHen I using -stdlib=libc++, the error (a linking error) is:
g++ -std=c++11 -stdlib=libc++ -Wall -pedantic -I. src/main.cpp -lpcrecpp -o bin/test obj/util.o obj/recognizer.o
Undefined symbols for architecture x86_64:
"RegularRule::analysis(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
Recognizer::readRegexRules(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in recognizer.o
"RegularRule::setIndex(int)", referenced from:
Recognizer::readRegexRules(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in recognizer.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bin/test] Error 1
My gcc version is:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
SO I'm confused. Can anybody help?
update
I think the problem lies in the pcre library
I tested a simple code like:
#include <iostream>
#include <pcrecpp.h>
using namespace std;
int main() {
cout << "hello world" << endl;
pcrecpp::RE re("h.*o");
return 0;
}
And the compiling error is:
Undefined symbols for architecture x86_64:
"pcrecpp::RE::Init(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, pcrecpp::RE_Options const*)", referenced from:
pcrecpp::RE::RE(char const*) in helloworld.cpp.o
"pcrecpp::RE::~RE()", referenced from:
_main in helloworld.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [hello] Error 1
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
make: *** [all] Error 2

Related

How to modify makefile for openMP inclusion

HI everybody I am a beginner for both openMP and makefile. Here is my problem.
I usually compile simple openMP code via terminale using:
g++-10 -o file.exe -fopenmp file.cxx
Now I want to modify a code, which consists in many file linked together, adding openMP libraries. Indeed I have to change the already existing makefile and I have no idea how to do it. The openMP libraries are used only in the file "esercizio1.1.cxx".
Here the makefile:
esercizio1.1 : esercizio1.1.o random.o
g++ -o esercizio1.1 esercizio1.1.o random.o
esercizio1.1.o : esercizio1.1.cxx funzioni.h random.h
g++ -c -o esercizio1.1.o esercizio1.1.cxx
random.o : random.cxx random.h
g++ -c -o random.o random.cxx
clean:
rm esercizio1.1
Here an example of how I tried to modify my makefile. I renamed my file and I added
g++-10 -fopenmp
to all the line at the same time, to all the line one per time. but still does not work. Here an example:
esercizio : esercizio.o random.o
g++-10 -fopenmp esercizio.o random.o -o esercizio
esercizio.o : esercizio.cc funzioni.h random.h
g++-10 -fopenmp esercizio.cc -o esercizio.o
random.o : random.cc random.h
g++ random.cc -o random.o
clean:
rm esercizio
Here is the error:
Undefined symbols for architecture x86_64:
"__ZN6Random6RannyuEv", referenced from:
_main._omp_fn.0 in ccA635Wn.o
"__ZN6Random8SaveSeedEv", referenced from:
_main in ccA635Wn.o
"__ZN6Random9SetRandomEPiii", referenced from:
_main in ccA635Wn.o
"__ZN6RandomC1Ev", referenced from:
_main in ccA635Wn.o
"__ZN6RandomD1Ev", referenced from:
_main in ccA635Wn.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [esercizio.o] Error 1
Does it exist a guide for makefile beginner?
Anyway I would appreciate if someone helped me. Thanks in advance.
"C++ compilers are picky and may come with different ABIs, thus mixing different C++ compilers in the same project isn't advised. You are compiling random.cc with g++, which on macOS is a symlink to Apple's clang++. Use g++-10 instead. Also, g++ -o random.o random.cc produces an executable file, not an object file. Leave it as g++-10 -c -o random.o random.cc."
credits to Hristo Iliev. Thank you.

Undefined symbols for architecture x86_64: "hex(QTextStream&)", referenced from: (Installing PyQwt-5.2.0 on Mac)

I am trying to install the emzed python package for LC/MS analysis. This package is dependent on PyQt4 and PyQWT. I have installed everything but have not been able to build PyQWT. I have jumped through so many errors and I have been stuck on this linking error for a while.
I have tried modifying the makefile (Qwt_version_info.mak) to pass it include directories. I do not know how to specify the appropriate linking library to get his too compile (the QTextStream, etc)
$ make -f qwt_version_info.mak
Are we linking yet?1
Are we linking yet?2
Are we linking yet?3
Are we linking yet?4
Are we linking yet?5
g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch x86_64 -headerpad_max_install_names -macosx_version_min 10.9.0 -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/10.0.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"hex(QTextStream&)", referenced from:
_main in qwt_version_info.o
"QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)", referenced from:
QTypedArrayData<unsigned short>::deallocate(QArrayData*) in qwt_version_info.o
"QTextStream::QTextStream(QIODevice*)", referenced from:
_main in qwt_version_info.o
"QTextStream::~QTextStream()", referenced from:
_main in qwt_version_info.o
"QTextStream::operator<<(char const*)", referenced from:
_main in qwt_version_info.o
"QTextStream::operator<<(int)", referenced from:
_main in qwt_version_info.o
"QFile::open(QFlags<QIODevice::OpenModeFlag>)", referenced from:
_main in qwt_version_info.o
"QFile::QFile(QString const&)", referenced from:
_main in qwt_version_info.o
"QFile::~QFile()", referenced from:
_main in qwt_version_info.o
"QString::fromAscii_helper(char const*, int)", referenced from:
QString::QString(char const*) in qwt_version_info.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [qwt_version_info.app/Contents/MacOS/qwt_version_info] Error 1
This is the makefile.
1591 $ cat qwt_version_info.mak
#############################################################################
# Makefile for building: qwt_version_info.app/Contents/MacOS/qwt_version_info
# Generated by qmake (2.01a) (Qt 4.8.7) on: Tue Aug 13 11:31:21 2019
# Project: qwt_version_info.pro
# Template: app
# Command: /usr/local/opt/qt#4/bin/qmake -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro
#############################################################################
####### Compiler, tools and options
CC = gcc
CXX = g++
DEFINES =
CFLAGS = -pipe $(DEFINES)
CXXFLAGS = -pipe -std=c++11 $(DEFINES)
INCPATH = -I/usr/local/etc/qt4/mkspecs/macx-g++ -I. -I../qwt-5.2/src -I/usr/local/Cellar/qt#4/4.8.7_5/lib/QtCore.framework/Versions/4/Headers -I/usr/local/Cellar/sip/4.19.8_12/include -I/Users/Danny/.virtualenvs/emzed2.7/lib/python2.7/site-packages/numpy/core/include
LINK = g++
LFLAGS = -headerpad_max_install_names
LIBS = $(SUBLIBS)
AR = ar cq
RANLIB = ranlib -s
QMAKE = /usr/local/opt/qt#4/bin/qmake
TAR = tar -cf
COMPRESS = gzip -9f
COPY = cp -f
SED = sed
COPY_FILE = cp -f
COPY_DIR = cp -f -R
STRIP =
INSTALL_FILE = $(COPY_FILE)
INSTALL_DIR = $(COPY_DIR)
INSTALL_PROGRAM = $(COPY_FILE)
DEL_FILE = rm -f
SYMLINK = ln -f -s
DEL_DIR = rmdir
MOVE = mv -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
export MACOSX_DEPLOYMENT_TARGET = 10.9
####### Output directory
OBJECTS_DIR = ./
####### Files
SOURCES = qwt_version_info.cpp
OBJECTS = qwt_version_info.o
DIST = /usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/mac.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base-macx.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/g++-macx.conf \
qwt_version_info.pro
QMAKE_TARGET = qwt_version_info
DESTDIR =
TARGET = qwt_version_info.app/Contents/MacOS/qwt_version_info
first: all
####### Implicit rules
.SUFFIXES: .o .c .cpp .cc .cxx .C
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.cc.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.C.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$#" "$<"
.c.o:
$(CC) -c $(CFLAGS) $(INCPATH) -o "$#" "$<"
####### Build rules
all: qwt_version_info.mak qwt_version_info.app/Contents/PkgInfo qwt_version_info.app/Contents/Resources/empty.lproj $(TARGET)
$(TARGET): $(OBJECTS)
#$(CHK_DIR_EXISTS) qwt_version_info.app/Contents/MacOS/ || $(MKDIR) qwt_version_info.app/Contents/MacOS/
$(LINK) -v $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
$(info Are we linking yet?1)
qwt_version_info.mak: qwt_version_info.pro /usr/local/etc/qt4/mkspecs/macx-g++/qmake.conf /usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf \
/usr/local/etc/qt4/mkspecs/common/mac.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf \
/usr/local/etc/qt4/mkspecs/common/gcc-base-macx.conf \
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf \
/usr/local/etc/qt4/mkspecs/common/g++-macx.conf
$(QMAKE) -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/unix.conf:
/usr/local/etc/qt4/mkspecs/common/mac.conf:
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/gcc-base.conf:
/usr/local/etc/qt4/mkspecs/common/gcc-base-macx.conf:
/usr/local/Cellar/qt#4/4.8.7_5/etc/qt4/mkspecs/common/g++-base.conf:
/usr/local/etc/qt4/mkspecs/common/g++-macx.conf:
qmake: FORCE
#$(QMAKE) -spec /usr/local/etc/qt4/mkspecs/macx-g++ -o qwt_version_info.mak qwt_version_info.pro
$(info Are we linking yet?2)
qwt_version_info.app/Contents/PkgInfo:
#$(CHK_DIR_EXISTS) qwt_version_info.app/Contents || $(MKDIR) qwt_version_info.app/Contents
#$(DEL_FILE) qwt_version_info.app/Contents/PkgInfo
#echo "APPL????" >qwt_version_info.app/Contents/PkgInfo
qwt_version_info.app/Contents/Resources/empty.lproj:
#$(CHK_DIR_EXISTS) qwt_version_info.app/Contents/Resources || $(MKDIR) qwt_version_info.app/Contents/Resources
#touch qwt_version_info.app/Contents/Resources/empty.lproj
:
#$(DEL_FILE)
#sed -e "s,#SHORT_VERSION#,1.0,g" -e "s,#TYPEINFO#,????,g" -e "s,#ICON#,,g" -e "s,#EXECUTABLE#,qwt_version_info,g" -e "s,#TYPEINFO#,????,g" >
dist:
#$(CHK_DIR_EXISTS) .tmp/qwt_version_info1.0.0 || $(MKDIR) .tmp/qwt_version_info1.0.0
$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/qwt_version_info1.0.0/ && (cd `dirname .tmp/qwt_version_info1.0.0` && $(TAR) qwt_version_info1.0.0.tar qwt_version_info1.0.0 && $(COMPRESS) qwt_version_info1.0.0.tar) && $(MOVE) `dirname .tmp/qwt_version_info1.0.0`/qwt_version_info1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/qwt_version_info1.0.0
$(info Are we linking yet?3)
clean:compiler_clean
-$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) *~ core *.core
####### Sub-libraries
distclean: clean
-$(DEL_FILE) -r qwt_version_info.app
-$(DEL_FILE) qwt_version_info.mak
compiler_clean:
####### Compile
$(info Are we linking yet?4)
qwt_version_info.o: qwt_version_info.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o qwt_version_info.o qwt_version_info.cpp
$(info Are we linking yet?5)
####### Install
install: FORCE
uninstall: FORCE
FORCE:
Any help is much appreciated.
Update:
under
/usr/local/Cellar/qt#4/4.8.7_5/lib/QtCore.framework I found a binary called QtCore. I renamed it libQtCore.so and when I linked it with this binary this is my new error message:
$ g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/local/Cellar/qt#4/4.8.7_5/lib/QtCore.framework -lQtCore
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -dynamic -arch x86_64 -headerpad_max_install_names -macosx_version_min 10.14.0 -o qwt_version_info.app/Contents/MacOS/qwt_version_info -L/usr/local/Cellar/qt#4/4.8.7_5/lib/QtCore.framework qwt_version_info.o -lQtCore -lc++ -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/10.0.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)", referenced from:
QTypedArrayData<unsigned short>::deallocate(QArrayData*) in qwt_version_info.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Now I just need help finding where the library binary for theQArrayData symbols is found. I have not been able to find anything helpful on google.
This may not be the complete answer yet, but its too large to put into a comment.
So lets focus on the single line here:
g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o
Now you are getting undefined references to things like: QByteArray and QTextStream. These all live in the library (IIRC) qtxcore or qtxcored (debug) where the x is the qt version. So I imagine for you it is libqt4core.so or libqt4cored.so.
So we need two bits of information, we need to know where this is install and which type (debug or release) you have.
The libraries are usually somewhere in /usr/lib/... and you will find libqt5core[d].so somewhere in there (IIRC /usr/lib/qt4/ - but that is a bit of a guess).
Lets assume you have the debug libraries - but both may well be there, then we can link that library in to your linker line:
Note: just run this line manually to start with and then we will add it to your makefile.
g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/lib/qt4 -lqt4cored
Here you can see that we have added a path to where the library is (-L...) and the library itself (-l...).
Now this will enable your linker to find QByteArray etc... but then you will probably have a few more things you are missing depending what bits of Qt you are using. Here is a list of other possible libs you may need to add:
libQt4Gui.so
libQt4Core.so
libQt4DBus.so
libQt4PrintSupport.so
libQt4Widgets.so
libQt4Network.so
libQt4XcbQpa.so
libQt4Svg.so
libicui18n.so
libicuuc.so
libicudata.so
Note: I got this list from another question I was answering a long while back so it may need editing and you may or may-not want to use the debug version (e.g. libQt5Gui.so -> libQt5Guid.so). The list is in no particular order.
So you could end up with:
g++ -v -headerpad_max_install_names -o qwt_version_info.app/Contents/MacOS/qwt_version_info qwt_version_info.o -L/usr/lib/qt4 -lqt4cored -licudata -licuuc ... etc...
Get this line working and then we can see about adding it to your makefile - adding the libs/paths is trivial.

Why does the linker complain “file was built for archive which is not the architecture being linked” when the architecture is correct?

When trying to build a binary (see MWE below) that links a static library using clang I am getting the following error message:
⟩⟩⟩ clang -o test bar.a test.o
ld: warning: ignoring file bar.a, file was built for archive which is not the architecture being linked (x86_64): bar.a
> Undefined symbols for architecture x86_64:
> "_bar", referenced from:
> _main in test.o
> "_foo", referenced from:
> _main in test.o
> ld: symbol(s) not found for architecture x86_64
But the architecture is correct and consistent (x86_64) according to lipo:
⟩⟩⟩ lipo -info test.o bar.a
input file bar.a is not a fat file
Non-fat file: test.o is architecture: x86_64
Non-fat file: bar.a is architecture: x86_64
otools -hv shows similar output. All object files are built for x86_64. So what does this error message mean?
Here’s a complete, minimal, working example to reproduce the problem shown above:
foo.c:
int foo(void) {
return 1;
}
bar.c:
int bar(void) {
return 2;
}
test.c:
#include <stdio.h>
int foo(void);
int bar(void);
int main(void) {
printf("foo = %d\n", foo());
printf("bar = %d\n", bar());
}
Compilation:
clang -c -o foo.o foo.c
ar rcs foo.a foo.o
clang -c -o bar.o bar.c
ar rcs bar.a foo.a bar.o
clang -c -o test.o test.c
clang -o test bar.a test.o
The error message is in fact misleading: The issue isn’t a mismatch in architecture, it’s the fact static libraries (.a files) cannot be nested:
⟩⟩⟩ nm bar.a
bar.a(bar.o):
0000000000000000 T _bar
(Note that the entry _foo from foo.a is missing!)
But since ar is originally a general-purpose archival utility, it has no qualms creating a nested archive via
ar rcs bar.a foo.a bar.o
As we can verify by listing its contents:
⟩⟩⟩ ar t bar.a
__.SYMDEF SORTED
foo.a
bar.o
To fix the problem, don’t nest archives but rather pack the object files directly:
rm bar.a
ar rcs bar.a foo.o bar.o
clang -o test bar.a test.o

linking assembly object file with C object file on OS X and can't find symbol

I have a library defined in libadd.asm, it exposes one "function" _add. I have a .c source file that refers to add and I'm trying to get the two object files to link, but am encountering this error regardless of the order in which I link the object files:
Undefined symbols for architecture x86_64:
"_add", referenced from:
_main in prog.o
Here's the code:
// prog.c
#include <stdio.h>
int add();
int main() {
printf("%d\n", add(4, 5));
return 0;
}
And here's the assembly file. It almost certainly doesn't respect the appropriate calling convention. I don't really understand what I should be doing to shuffle the values between registers. (That's what I was trying to figure out originally.)
; libadd.asm
_add:
add eax, edx
ret
Here's what I'm using to the tiny project. I'm intentionally shadowing the implicit .c.o rule with one that does as little as possible and ignores *FLAGS. I'm using cc to drive the linker because that's the simplest way I know to link in the c runtime/standard library/whatever it's called. I've always tried linking with prog.o and libadd.o in the other order.
all: prog
prog: prog.o libadd.o
$(CC) -o prog $^
%.o: %.asm
nasm -f macho64 -o $# $<
%.o: %.c
$(CC) -c -o $# $<
clean:
$(RM) $(wildcard *.o)
running make produces the following output
cc -c -o prog.o prog.c
nasm -f macho64 -o libadd.o libadd.asm
cc -o prog prog.o libadd.o
Undefined symbols for architecture x86_64:
"_add", referenced from:
_main in prog.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [prog] Error 1
Exit 2
libadd.o gets assembled successfully and appears to have the right symbol in it.
% nm libadd.o
0000000000000000 t _add
Why is ld complaining that it can't find the symbol?

g++ Rcpp Undefined symbols for architecture x86_64 on osx

I am trying to create a dylib file in OSX El Capitain from a C++ source file to read into R via Rcpp. Here is a grossly simplified example of what I've created:
//test.cpp
#include <Rcpp.h>
RcppExport SEXP dosum(SEXP _a, SEXP _b){
double a = Rcpp::as<double>(_a);
double b = Rcpp::as<double>(_b);
return Rcpp::wrap(a+b);
}
When I compile/link using the following Makefile on a Linux server that is available to me at my university,
CC=g++
# note the use of c++14, used to use c++11
all: test
test :
${CC} -DNDEBUG \
-I. \
-I/usr/share/R/include \
-I/server/linux/lib/R/3.0/x86_64/site-library/Rcpp/include \
-I/usr/share/Rcpp_0.12.3/include \
-fpic -O3 -pipe \
-std=c++1y \
-c test.cpp
${CC} -shared -o test.so test.o
clean:
#find . \( -name "*.o" -o -name "*.so" \) -exec rm {} \;
I get the desired test.so file, which I can then read in during an R session via dyn.load('test.so'). Once it has been loaded, I can use the function dosum() via dosum(x,y). Great.
But I would like to do the exact same thing in OSX El Capitain on my personal Mac. I have tried many variations of a Makefile, and am currently using,
CC=g++
all: temp
temp:
${CC} \
-I. \
-I/usr/share/R/include \
-I/usr/local/include/Rcpp/Rcpp_0.12.5/inst/include \
-fPIC \
-c temp.cpp
${CC} -dynamiclib *.o -o temp.dylib
clean:
#find . \( -name "*.o" -o -name "*.dylib" \) -exec rm {} \;
When I run this Makefile, I get the following,
g++ \
-I. \
-I/usr/share/R/include \
-I/usr/local/include/Rcpp/Rcpp_0.12.5/inst/include \
-fPIC \
-c temp.cpp
g++ -dynamiclib *.o -o temp.dylib
Undefined symbols for architecture x86_64:
"_REprintf", referenced from:
Rcpp::Rstreambuf<false>::xsputn(char const*, long) in temp.o
Rcpp::Rstreambuf<false>::overflow(int) in temp.o
"_R_FlushConsole", referenced from:
Rcpp::Rstreambuf<true>::sync() in temp.o
Rcpp::Rstreambuf<false>::sync() in temp.o
"_R_GetCCallable", referenced from:
dataptr(SEXPREC*) in temp.o
"_R_NilValue", referenced from:
Rcpp::Rcpp_protect(SEXPREC*) in temp.o
Rcpp::Shield<SEXPREC*>::~Shield() in temp.o
"_Rf_allocVector", referenced from:
SEXPREC* Rcpp::internal::primitive_wrap__impl__cast<double>(double const&, Rcpp::traits::integral_constant<bool, false>) in temp.o
"_Rf_coerceVector", referenced from:
SEXPREC* Rcpp::internal::basic_cast<14>(SEXPREC*) in temp.o
"_Rf_length", referenced from:
double Rcpp::internal::primitive_as<double>(SEXPREC*) in temp.o
"_Rf_protect", referenced from:
Rcpp::Rcpp_protect(SEXPREC*) in temp.o
"_Rf_unprotect", referenced from:
Rcpp::Shield<SEXPREC*>::~Shield() in temp.o
"_Rprintf", referenced from:
Rcpp::Rstreambuf<true>::xsputn(char const*, long) in temp.o
Rcpp::Rstreambuf<true>::overflow(int) in temp.o
"_TYPEOF", referenced from:
SEXPREC* Rcpp::r_cast<14>(SEXPREC*) in temp.o
SEXPREC* Rcpp::internal::basic_cast<14>(SEXPREC*) in temp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [temp] Error 1
That is, it appears that things are getting garbled and an underscore is being added at the front of the variables in question. What am I doing wrong? I have tried adding/dropping various flags like -fpic, -std=XXX and so on.
I have found related questions, but they appear to be cases where the original poster is confusing how to use Rcpp in the first place. Here, I just want to do on the Mac what I can do in Linux. I have no reason to believe that there is a fundamental difference between the header files on my Mac versus those on the Linux box, but I have not yet checked in detail.
FWIW, I can create dylibs using the same approach on my Mac as long as they don't use Rcpp (for example, a simple cout << "hello world" <<endl; function), so maybe my Rcpp installation is somehow messed up.
Why are you using a Makefile?
It all works if you just let R do its business. Here is one-to-four-liner (depending on how you count):
R> cppFunction("SEXP dosum(SEXP a_, SEXP b_){
double a = Rcpp::as<double>(a_);
double b = Rcpp::as<double>(b_);
return Rcpp::wrap(a+b);
}")
R> dosum(4, 7)
[1] 11
R>
Note, however, that I had to revert your invalid identifier _a, _b to valid a_, b_.
All this can of course also be had as a one-liner given the templated conversions we get for free:
R> cppFunction("double dosum2(double a, double b) { return a+b; }")
R> dosum2(5, 8)
[1] 13
R>

Resources