embedding Julia in C/C++ on OSX - c

I am trying to compile a very simple C/C++ program to call Julia functions. Following the instructions that you find on the Julia documentation page, I set up my link path to /Users/william.calhoun/Desktop/romeo/lib/julia looking for libjulia.so and I set up my include path to /Users/william.calhoun/Desktop/romeo/include/julia looking for julia.h
I have a C file called test.c which runs the following code:
#include <stdio.h>
#include "skeleton.h"
#include <julia.h>
int main(int argc, const char * argv[]) {
jl_init(NULL);
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook();
return 0;
}
However this yields the following error:
Undefined symbols for architecture x86_64:
"_jl_atexit_hook", referenced from:
_main in test.o
"_jl_eval_string", referenced from:
_main in test.o
"_jl_init", referenced from:
_main in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I am not doing anything other than calling functions defined properly (hopefully) within the Julia source code. What am I doing wrong? This seems like the simplest example and I can't figure it out.
Any help would be much appreciated!

Linking to libjulia (libjulia.dynlib on OS/X)
This error is a result of not linking to libjulia, as all of the symbols (_jl_atexit_hook, _jl_eval_string, _jl_init) are located in that library. Broadly, for all 3 of the following platforms (Windows, OS/X, Linux), the approach is similar, and though the location of the libjulia library is different on Windows than the other 2 this stackoverflow question is applicable. Also to be completely accurate, on OS/X, dynamic libraries have the extension .dynlib not .so as they do on Linux.
The link step
For simplicity, assuming you've compiled to object code (there is a file called embed.o), here's the link step.
cc -o embed embed.o -L/Users/william.calhoun/Desktop/romeo/lib/julia -Wl,-rpath,/Users/william.calhoun/Desktop/romeo/lib/julia -ljulia
There are 2 important things to note here.
Linking using -ljulia will allow the linker to resolve all of the above symbols.
Since this is a dynamic library and that dynamic library is located in a non standard location (e.g. not in /usr/lib), the dynamic linker will not be able to find it at run time unless you give it special instructions on how to find it. The -rpath directive causes the linker to insert the path /Users/william.calhoun/Desktop/romeo/lib/juliainto the list of paths to search.

Related

Compiling without main function (MacOS)

So I am trying to compile ,link and run a program without the main function.This is the code:
#include <stdio.h>
#include <stdlib.h>
int my_main()
{
printf("Hello world!\n");
return 0;
}
void _start()
{
exit(my_main());
}
Tried to compile with the command : gcc -nostartfiles nomain.c . While it does compile and produces the a.out file on a Debian vm, I am unable to compile it in my macOS Catalina v10.15.2. I am using the latest version of gcc. The message I am receiving when trying to compile is :
Undefined symbols for architecture x86_64: "_main", referenced from:
implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status
So far I have tried to change _start to start but still getting the same result. As I understand the compilation process is different depending on the OS.
Note: There is no problem I am trying to solve here , just curiosity.
Thank you in advance
On macOS 10.14.6 with Xcode 11.3, the code in the question compiles and links with the command:
clang -Wl,-e, -Wl,__start <Name of Your Source File>
The resulting executable appears to work. However, since it bypasses the startup code for the C environment, you should not expect that using routines from the C library or other C features will work properly.
Note that two underscores are needed before start in the above command because the source code contains one and another is added by the C compiler. If the code is changed to use start instead of _start, then the command would use one underscore:
clang -Wl,-e, -Wl,_start <Name of Your Source File>
The switches -Wl,-e, -Wl,_start pass -e _start to the linker, which tells it to use _start as the address of the initial code to execute. It is not clear to me why this bypasses the default loading of the C-run-time-startup object module, which also defines _start. I would have preferred to use a linker switch that tells it not to load that module, but I did not find one in the man page for ld. Experimentation suggests that, by default, ld loads the default object module, and it refers to main, which results in a link error, but, when -e _start is used, the linker sets the program’s _start symbol as the startup address and does not load the default object module.
I'm pretty sure you can compile any C-source without main().
The problem will be with the linker trying to create an executable, which won't work without main().

MATLAB Generated C Code Compilation Error

I have a MATLAB function that has signal processing and machine learning and I wanted to test it on another OS like linux. So I use codegen to generate C code for that function. When I come to run it (predictActivityFromSignalBuffer) on the command line, this is what I get:
MacBook-Pro-2:predictActivityFromSignalBuffer kareem$ gcc predictActivityFromSignalBuffer.c
Undefined symbols for architecture x86_64:
"_featuresFromBuffer", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
"_main", referenced from:
implicit entry/start for main executable
"_mynn", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
"_rtIsNaN", referenced from:
_predictActivityFromSignalBuffer in predictActivityFromSignalBuffer-1a1886.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What is this error telling me exactly? I have no idea how to debug this or where to start/look.
Did you really just call
$ gcc predictActivityFromSignalBuffer.c
without any other dependencies? Usually there come a lot of other files with a code generation that have to be linked.
I do not know what you have done to produce your .c file. I recommend to use the coder wizard by typing
coder
in the Matlab command window. This will guide you through the whole process of code generation and also offers a lot of support and testing possibilities. You can also choose to compile your functions to ready-to-use DLL libraries or executatables. Just have a look at it.

Allow double floating point comparisons with Unity unit testing framework from Throw The Switch

I'm having some trouble somewhere with the linker while trying to compile a test written using the Unity testing framework by Throw The Switch. I have other tests that compile and run perfectly fine so I'm definitely just missing something in enabling the assertion helper for double floating point comparisons.
There is documentation in the header file telling us how to enable double floating point comparisons.
* - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
However, I end up with this error:
Undefined symbols for architecture x86_64:
"_UnityAssertDoublesWithin", referenced from:
_test_example in main-6fae82.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I wrote up the simplest example possible to duplicate this:
#define UNITY_INCLUDE_DOUBLE
#include "unity.h"
void test_example(void)
{
TEST_ASSERT_EQUAL_DOUBLE(1.234, 1.234);
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_example);
return UNITY_END();
}
The contents of the CWD of the example and the exact command used to call clang (showing the same error again):
$ ls
main.c unity.c unity.h unity_internals.h
$ clang unity.c main.c
Undefined symbols for architecture x86_64:
"_UnityAssertDoublesWithin", referenced from:
_test_example in main-ee77c2.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Same exact thing happens with gcc (but it's actually just calling clang under the hood).
I'm pretty sure I'm just missing one tiny step but for the life of me I can't see what it is right now. Thanks in advance for your help.
I have this working on my minimal tests by using the same define in the unity_config.h file and adding UNITY_INCLUDE_CONFIG_H as a compiler -D flag (gcc). But running with the #define in the source does not do the same trick
You can find a full copy of a unity_config.h file on the ThrowTheSwitch GitHub repo. I usually just throw it in the same folder Unity is in.
It also works if you add the define directly into the unity.h file as specified in the comments in that file (that you quote in your question) which says
All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above.
i.e. in unity.h
#define UNITY_INCLUDE_DOUBLE
#include "unity_internals.h"
...
Why your initial tactic, which should essentially be the same thing, does not work, I do not know.
Looks like this works when defining UNITY_INCLUDE_DOUBLE with the -D flag to clang/gcc. For example:
$ clang -DUNITY_INCLUDE_DOUBLE -DUNITY_DOUBLE_PRECISION=1e-12f unity.c main.c
$ ./a.out
main.c:10:test_example:PASS
-----------------------
1 Tests 0 Failures 0 Ignored
OK

Creating a dylib which gets linked at runtime

I am trying to create a dynamic library which is meant to be linked and loaded into a host environment at runtime (e.g. similar to how class loading works in Java). As such, I want the dynamic library to be left with a few "dangling" references, which I expect it to pick up from its host environment when it is loaded into that environment.
My problem is that I cannot figure out how to create the dynamic library without explicitly linking it to existing symbols. I am hoping to produce a dynamic library that does not depend on a specific host executable (or host library), rather one that is able to be loaded (e.g. by dlopen) in any host as long as the host makes a couple symbols available for use.
Right now, any linking command I've tried results in a complaint of missing symbols. I'd like it to allow symbols to be missing (ideally, just particularly specified symbols).
For example, here's a transcript with the error on OS X:
$ cat frotz.c
void blort(void);
void run(void) {
blort();
}
$ cc -c -o frotz.o frotz.c
$ cc -dynamiclib -o libfrotz.dylib frotz.o
Undefined symbols for architecture x86_64:
"_blort", referenced from:
_run in frotz.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If I do the same thing using a GNU toolchain (on Linux), it helpfully tells me:
$ gcc -shared -o libfrotz.so frotz.o
/usr/bin/ld: frotz.o: relocation R_X86_64_PC32 against undefined symbol `blort'
can not be used when making a shared object; recompile with -fPIC
and indeed, adding -fPIC to the C compile command seems to fix the problem in that environment. However, it doesn't seem to have any effect in OS X.
All the other dynamic-linking questions I could find on SO seem to be about the more usual arrangement of libraries, where a library is being built to be linked into an executable before that executable runs, rather than the other way around. The closest related question I found was this:
Can an executable be linked to a dynamic library after its built?
which unfortunately has very little info, none of it relevant to the question I'm asking here.
UPDATE: I distilled the info from the answer along with everything else I'd figured
out, and put together this example:
https://github.com/danfuzz/dl-example
As far as my knowledge goes, you want to use weak linkage:
// mark function as weakly-linked
extern void foo() __attribute__((weak));
// inform the linker about that too
clang -dynamiclib -o bar.dylib bar.o -flat_namespace -undefined dynamic_lookup
If a weak function can be resolved at runtime, it will then be resolved. If it can't, it will be NULL, instead of generating a runtime (or, obviously, link-time) error.

Undefined symbols for architecture x86_64 "_min"

I'm having a problem using min() and max() function in my C project. I've imported math.h, but when I compile the file I keep getting the following error (a similar error is displayed even using gcc instead of llvm):
Undefined symbols for architecture x86_64:
"_min", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I think the problem is that there isn't a 64 bit library of math.h... or the compiler can't find it. I'm using Mac OS X 10.7. How may I fix this problem?
Even though I can see "min" defined in libSystem.dylib, I don't think there's an exported header for that. And I can't figure out where "_min" is coming in from, in terms of the include files.
Normally "min" is referred to with a macro or with your own function. Check out this very related question somebody else asked a while back.
If you look in math.h, there are some "min" type functions in there but they are for floats and doubles. If you are just working with integers or custom types, roll your own function.

Resources