I am trying to create a shared library on the MAC using following the simple example at https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/CreatingDynamicLibraries.html
I have really dumbed it down to one function to try to get a function exported by clang in a library. My source code is as follows:
#define EXPORT __attribute__((visibility("default")))
EXPORT
void foo(){
int x = 1 + 3;
}
my compile line is
clang -dynamiclib lib.c -current_version 1.0 -compatibility_version 1.0 -fvisibility=hidden -o lib.dylib
This compiles fine and produces lib.dylib on my macbook. Now I would expect the nm tool to show my foo() export but the foo method is not exposed
nm -gu lib.dylib
returns only
dyld_stub_binder
I have been banging my head against this for a day now and it make no sense. Does anyone know what is wrong with this approach.
The answer is that using nm does not output what I expected i found that calling the method actually works using these steps. I wrote another program that uses this library as a test in it works fine. Spent too much time not testing the solution correctly.
Related
I have compiled a c++ code using g++ -std=c++11 -o main main.cpp -pthread and it compiled fine however if I compile the same code using gcc -std=c++11 -o main main.cpp -pthread it does not compile and throws error. The program uses threading which properly taken care of using -pthread option while compiling. For the reference I am attaching the code below. Any help is highly appreciated.
#include <iostream>
#include <thread>
class foo
{
public:
void bar(int loop_num)
{
for (int i = 0; i < loop_num; ++i) {
std::cout << "Thread executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
int main()
{
int n = 0;
foo f;
std::thread t1(&foo::bar, &f, 5);
t1.join();
}
If you’ve written C++ code with GCC, you’ll know that you need to use the program g++, both for compilation and linking. For multi-module programs, this means every .cpp file gets compiled with g++, and then the entire program must be linked separately using g++. If you try to link the program using gcc, it will almost work, but you’ll get a lot of “undefined reference” errors, like this:
test.cpp:(.text+0x11): undefined reference to `std::cout'
The need to use g++ to link the entire program causes trouble when you have a very complicated build process you don’t have full control of. For instance, I’m trying to link C++ code with Mercury, and I have to use the Mercury linker, which in turn calls gcc.
So just a quick tip: If you are forced to use gcc to link the program, just add the library “stdc++”, as you would any other library, and it will work. That is, add the option “-lstdc++” to your GCC linker command line. For example:
g++ -c hello.cpp
gcc -lstdc++ -o hello hello.o
I assume the error you get looks something like this:
/tmp/ccUKAq0K.o: In function `main':
main.cpp:(.text+0x59): undefined reference to `std::thread::join()'
/tmp/ccUKAq0K.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0xb6): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0xcb): undefined reference to `std::ios_base::Init::~Init()'
/tmp/ccUKAq0K.o: In function `std::thread::~thread()':
main.cpp:(.text._ZNSt6threadD2Ev[_ZNSt6threadD5Ev]+0x1d): undefined reference to `std::terminate()'
(And so on.)
C++ programs which use the standard library (so most of them) need to be linked using g++, not gcc. Only the g++ compiler driver links in most of the standard library. The gcc compiler driver compiles C++ programs, just like g++, but when the linker is invoked, the program is treated as a C program, which usually leads to linker errors.
Try adding the -lrt flag after the pthread one.
I am getting compiler error "no matching function for call to 'make_shared'" whenever I try to use a constructor that takes any arguments. So, for example:
std::shared_ptr<int> foo = std::make_shared<int> ();
works fine. But,
std::shared_ptr<int> foo = std::make_shared<int> (10);
Gives the following error:
/usr/bin/clang -g -Wall -Wextra -Wc++11-extensions -c ./test.cpp
./test.cpp:7:30: error: no matching function for call to 'make_shared'
std::shared_ptr<int> foo = std::make_shared<int> (10);
^~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4700:1: note: candidate function [with _Tp = int, _A0 = int]
not viable: expects an l-value for 1st argument
make_shared(_A0& __a0)
I took the above code directly from here http://www.cplusplus.com/reference/memory/make_shared/
and that code runs fine on cpp.sh web site. I suspect that there is something wrong with my compiler set up. Running in iTerm on a macbook. Also, I get the same error even if I remove the various options to clang shown above. Any ideas? Is it possible that my header file for needs to be updated? It's from Sep 4 2015. Seems recent enough for C++11 to work.
$ /usr/bin/clang --version
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
$ ls -l /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory
-rw-r--r-- 1 root wheel 174919 Sep 4 2015 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory
The error message is complaining you using an prvalue 10. Try to use
int avar = 10;
auto foo = std::make_shared<int> (avar);
It is interesting to see what happens when using a lvalue.
Did you build the std library locally? If you are, maybe you could try to rebuild again or grab a prebuilt library from somewhere.
I tested the code on https://godbolt.org/ with configuration x86-64 clang 7.0.0 and -std=c++11. it works fine. Even you using iOS, it should be good on that os I guess.
I also see you using -Wc++11-extensions when you building. Try use -std=c++11 instead maybe?
Edit by DG: As noted in my comment below, this last suggestion, "Try use -std=c++11," worked! With -std=c++11 then all values (lvalues, rvalues, prvalues, etc.) work fine. See comments below.
I am trying to write a game similar to code hunt (https://www.codehunt.com/about.aspx)
So How this will work, is the player can modify a .cpp file, which will be compiled and and ran within the code, but I have problems about how to compile it.
I'am using the latest g++ compiler, and this is how I try to achive this:
void Builder::build(const char* file){
std::string s = "g++ ";
s += file;
s += " -o test.o";
system(s.c_str());
}
Where we get the .cpp file's name, and this code piece is supposed to build test.o
This is just a test now, it might get more complex, I just wanted to test if the compiler will work within the code, but I get this error message when I try to run this:
c:/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../libmingw32.a(main.o):(.text.startup+0xa7):undefined reference to 'WinMain#16'
collect2.exe: error: ld returned 1 exit status
PATH for mingw is set correctly, I checked.
I am using Windows 8.1, g++ 4.9.3 and Code::Blocks.
In Windows execution doesn't normally start at the main functions, it starts at the WinMain function, which takes some Windows-specific arguments. You should read e.g. this WinMain reference for more information.
That some programs still seems to start at a main function is because there is an object file linked with the program that contains the WinMain function which calls your main function.
OK I'm an idiot, so the problem was that I was trying to build a file whitout a main function. This was deliberat design choice at first, but...well yeah. Sorry about that.
Thank you Joachim Pileborg for leading me to it.
I've got a file, test.lex, which I run through as
$ flex test.lex
That gives me lex.yy.c, which I try to compile with:
$ gcc lex.yy.c -lfl
This gives me the error ld: library not found for -lfl. I know the Flex specification is correct and lex.yy.c compiles fine on a Linux machine. Any suggestions?
Edit: I'm using the flex supplied by Apple.
Some systems make libfl a separate package from flex, as it is rarely needed. The libfl library just contains two functions:
int main() {
while (yylex());
return 0;
}
int yywrap() {
return 1;
}
Normally you'll want your own main function rather than the one from libfl, and defining yywrap yourself is trivial. Alternately, you can use %option noyywrap and not need it at all.
In your case, try just getting rid of the -lfl option. If you get an error about yywrap, add%option noyywrap to the first section of your test.lex file.
old topic but accepted answer did not help me.
so I'm adding this answer.
on macos use -ll (as in "library lex").
valid for macos 10.14 mojave.
also as #Chris Dodd said you can get rid of this dependency by specifying %option noyywrap in .l file and providing own main routine .y file.
I am a newbie in Linux gcc. I am writing a simple code to learn the weak attribute in Linux gcc.
See my sample code:
weakref.c, the main file. I want to the file could work with or without foo method being defined.
#include <stdio.h>
extern void foo(void) __attribute__((weak));
int main() {
if (foo){
foo();
printf ("foo is defined\n");
} else {
printf("foo is not defined\n");
}
}
so, I run the following command to compile it and run it:
gcc weakref.c -o main_static
./main_static
and the output is "foo is not defined", which is what I expected.
Then I created a new file libfoo.c, see below:
#include <stdio.h>
void foo() {
printf("Print in foo.\n");
}
I attempted 3 ways to try to make main file work with the libfoo.c:
Compile the libfoo.c and weakref.c and link the object files.
Compile the libfoo.c as a static library, and link it with the object file of weakref.c
Compile the libfoo.c as a shared library, and link it with the object file of weakref.c
Only the 3rd way works and get the following output:
Print in foo.
foo is defined
Could you please let me know if the weak ref only works with a shared library, and why? Thanks a lot!
let me know if the weak ref only works with a shared library
Not at all.
Both 1. and 3. are expected to produce "foo is defined".
The 2. is not expected to pull libfoo.o from libfoo.a, because unresolved weak reference from weakref.o does not count as unresolved symbol for the purpose of pulling an object from an archive library. However, you can force libfoo.o to be pulled into the link like so: gcc weakref.o -lfoo -ufoo, and then you should again get "foo is defined".
Now that I stated what should happen, let's see if the practice agrees. Transcript from a Linux/x86_64 system, using gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 and GNU ld (GNU Binutils for Ubuntu) 2.20.1-system.20100303:
$ gcc -c weakref.c libfoo.c
$ ar ruv libfoo.a libfoo.o
ar: creating libfoo.a
a - libfoo.o
$ gcc weakref.o && ./a.out
foo is not defined
This is your #1:
$ gcc weakref.o libfoo.o && ./a.out
Print in foo.
foo is defined
As you can see #1 "works" as I expected, and not as you claimed. You must have made some mistake somewhere.
This is your #2:
$ gcc weakref.o -L. -lfoo && ./a.out
foo is not defined
Your #2 again, but forcing libfoo.o to be pulled into the link:
$ gcc weakref.o -L. -lfoo -ufoo && ./a.out
Print in foo.
foo is defined