How to link a C library to an Assembly library on Mac with clang - macos

I have this in my C library:
myc:
#clang -I . -dynamiclib \
-undefined dynamic_lookup \
-o myc.dylib myc.c
.PHONY: myc
And this in my assembly library:
buildasm:
#nasm -f macho64 myasm.asm
#clang -o myasm myasm.o myc.dylib
# #ld -macosx_version_min 10.13.0 \
# -lSystem -o myasm \
# myasm.o
#./myasm
.PHONY: buildasm
I would like to then have a third either assembly or C project which loads the assembly library. But I can't get this C -> assembly working. I also don't have dyld the "dynamic loader" on Mac installed, so if possible I would prefer not to install any special tools, but if required I would like to know how to do the linking with the tool.
If I make the buildasm into this:
buildasm:
#nasm -f macho64 myasm.asm
#ld -macosx_version_min 10.13.0 \
-lSystem -o myasm \
myasm.o myc.dylib
#./myasm
.PHONY: buildasm
it compiles without any errors, but when it runs with ./myasm it gives:
Undefined symbols for architecture x86_64:
"my_c_function", referenced from:
start in myasm.o
ld: symbol(s) not found for inferred architecture x86_64
If I do this basically in asm:
extern my_c_function
start:
call my_c_function
And something like this in C:
extern void my_c_function() {
}
Wondering what would make this work.

Related

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.

How to run manually produce an elf executable using ld?

I'm trying to get my head around how the linking process works when producing an executable. To do that I'm reading Ian Taylor's blog series about it, but a lot of it is beyond me at the moment - so I'd like to see how it works in practice.
At the moment I produce some object files and link them via gcc with:
gcc -m32 -o test.o -c test.c
gcc -m32 -o main.o -c main.c
gcc -m32 -o test main.o test.o
How do I replicate the gcc -m32 -o test main.o test.o stage using ld?
I've tried a very naive: ld -A i386 ./test.o ./main.o
But that returns me these errors:
ld: i386 architecture of input file `./test.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file `./main.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
./test.o: In function `print_hello':
test.c:(.text+0xd): undefined reference to `_GLOBAL_OFFSET_TABLE_'
test.c:(.text+0x1e): undefined reference to `puts'
./main.o: In function `main':
main.c:(.text+0x15): undefined reference to `_GLOBAL_OFFSET_TABLE_
I'm most confused by _start and _GLOBAL_OFFSET_TABLE_ being missing - what additional info does gcc give to ld to add them?
Here are the files:
main.c
#include "test.h"
void main()
{
print_hello();
}
test.h
void print_hello();
test.c
#include <stdio.h>
void print_hello()
{
puts("Hello, world");
}
#sam : I am not the best people to answer your question because I am a beginner in compilation. I know how to compile programs but I do not really understand all the details (https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools)
So, I decided this year to try to understand how compilation works and I tried to do, more or less, the same things as you tried a few days ago. As nobody has answered, I am going to expose what I have done but I hope an expert will supplement my answer.
Short answer : It is recommended to not use ld directly but to use gcc directly instead. Nevertheless, it is, as you write, interesting to know how the linking process works. This command works on my computer :
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o /usr/lib/crtn.o
Very Long answer :
How did I find the command above ?
As n.m suggested, run gcc with -v option.
gcc -v -m32 -o test main.o test.o
... /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 ... (many
options and parameters)....
If you run ld with these options and parameters (copy and paste), it should work.
Try your command with -m elf_i386 (cf. collect2 parameters)
ld -m elf_i386 test.o main.o
ld: warning: cannot find entry symbol _start; ....
Look for symbol _start in object files used in the full ld command.
readelf -s /usr/lib/crt1.o (or objdump -t)
Symbol table '.symtab' contains 18 entries: Num: Value Size
Type Bind Vis Ndx Name... 11: 00000000 0 FUNC
GLOBAL DEFAULT 2 _start
Add this object to your ld command :ld -m elf_i386 test.o main.o /usr/lib/crt1.o
... undefined reference to `__libc_csu_fini'...
Look for this new reference in object files. It is not so obvious to know which library/object files are used because of -L, -l options and some .so include other libraries. For example, cat /usr/lib/libc.so. But, ld with --trace option helps. Try this commandld --trace ... (collect2 parameters)At the end, you should findld -m elf_i386 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc_nonshared.a /lib/libc.so.6 /usr/lib/crti.oor shorter (cf. cat /usr/lib/libc.so) ld -m elf_i386 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o
It compiles but it does not run (Try to run ./test). It needs the right -dynamic-linker option because it is a dynamically linked ELF executable. (cf collect2 parameters to find it) ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o But, it does not run (Segmentation fault (core dumped)) because you need the epilogue of the _init and _fini functions (https://gcc.gnu.org/onlinedocs/gccint/Initialization.html). Add the ctrn.o object. ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test test.o main.o /usr/lib/crt1.o /usr/lib/libc.so /usr/lib/crti.o /usr/lib/crtn.o./test
Hello, world

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>

Breaking NASM files into multiple with link errors on OS X

My base assembler file foidlrt.asm started getting a bit too large so I broke it up into two. Here is the entirety of the second file folder_stdio.asm:
; foidl_stdio.asm
%include "foidlstnd.inc"
section .text
DEFAULT REL
global foidl_fclose ; Raw file close
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; foidl_close
; Raw file close
; REGISTERS (1):
; RDI file handle
; CALLS:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
foidl_fclose:
mov rax,SYSCALL_FILE_CLOSE ; 0x2000006
syscall
ret
However, now when I build I am now getting this error from make despite the global declaration in the new file:
nasm src/foidlrt.asm -f macho64 --prefix _ -g -O0 -Iincludes/ -o asmobjs/foildrt.o
nasm src/foidlrt.asm -f macho64 --prefix _ -g -O0 -Iincludes/ -o asmobjs/foidl_stdio.o
libtool -static -s -o libs/libfoidlrt.a asmobjs/foildrt.o asmobjs/foidl_stdio.o
gcc src/testlink.c -L libs -l foidlrt -Wall -g -L. -Wl,-pie -I. -o bin/testlink
Undefined symbols for architecture x86_64:
"_foidl_fclose", referenced from:
_main in testlink-4b5ad3.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Version information:
XCode - 7.2.1 (7C1002)
nasm - NASM version 2.12 compiled on Feb 28 2016
gcc - Apple LLVM version 7.0.2 (clang-700.1.81)
RESOLVED
Error was all mine, makefile rule was bad. Working as expected now.

Compile assembler in nasm on mac os

So, i write some instruction on asm, and compile them.
nasm -f macho test.asm
Now, nasm generate obj file, test.o
gcc test.o
Returned next error:
ld: warning: ignoring file test.o, file was built for unsupported file
format which is not the architecture being linked (x86_64)
Undefined
symbols for architecture x86_64: "_main", referenced from:
start in crt1.10.6.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
in gcc line, i used -arch i386 (x86_64), returned same error.
Can anybody help? :)
These commands work for me (OS X 10.12 x64):
nasm -f macho test.asm -DDARWIN
ld -o test test.o -arch i386 -lc -no_pie -macosx_version_min 10.12 -lSystem
macho is a 32 bit format.
Try to use macho64 instead of macho. Complete line:
nasm -f macho64 test.asm
Try to update your nasm version and use the following command:
/usr/local/bin/nasm -f macho64 ${file}
ld -o ${file_path}/${file_base_name} -e _main ${file_path}/${file_base_name}.o
${file_path}/${file_base_name}

Resources