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.
Related
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.
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 have used the C code from the following verbatim: https://wiki.tcl-lang.org/page/Hello+World+as+a+C+extension
/*
* hello.c -- A minimal Tcl C extension.
*/
#include <tcl.h>
static int
Hello_Cmd(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
Tcl_SetObjResult(interp, Tcl_NewStringObj("Hello, World!", -1));
return TCL_OK;
}
/*
* Hello_Init -- Called when Tcl loads your extension.
*/
int DLLEXPORT
Hello_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
/* changed this to check for an error - GPS */
if (Tcl_PkgProvide(interp, "Hello", "1.0") == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "hello", Hello_Cmd, NULL, NULL);
return TCL_OK;
}
My command for compiling is nearly verbatim except for the last character, indicating Tcl version 8.6 rather than 8.4, and it compiles without error:
gcc -shared -o hello.dll -DUSE_TCL_STUBS -I$TCLINC -L$TCLLIB -ltclstub86
Then I created the following Tcl program:
load hello.dll Hello
puts "got here"
But when running it with tclsh get the following error:
cannot find symbol "Hello_Init"
while executing
"load ./hello.dll Hello"
(file "hello.tcl" line 1)
So I am essentially following a couple of suggestions from Donal Fellows answer here: cannot find symbol "Embeddedrcall_Init" The OP there however commented that, like me, the suggestion(s) hadn't resolved their issue. One thing that I didn't try from that answer was "You should have an exported (extern "C") function symbol in your library" -- could that be the difference maker? Shouldn't it have been in the example all along then?
At the suggestion of somebody on comp.lang.tcl I found "DLL Export Viewer" but when I run it against the DLL it reports 0 functions found :( What am I doing wrong?
Could it be an issue with MinGW/gcc on Windows, and I need to bite the bullet and do this with Visual Studio? That's overkill I'd like to avoid if possible.
The core of the problem is that your function Hello_Init is not ending up in the global symbol table exported by the resulting DLL. (Some linkers would put such things in as _Hello_Init instead of Hello_Init; Tcl adapts to them transparently.) The symbol must be there for Tcl's load command to work: without it, there's simply no consistent way to tell your extension code what the Tcl_Interp context handle is (which allows it to make commands, variables, etc.)
(If you'd been working with C++, one of the possible problem is a missing extern "C" whose actual meaning is to turn off name mangling. That's probably not the problem here.)
Since you are on Windows — going by the symbols in your DLL, such as EnterCriticalSection and GetLastError — the problem is probably linked to exactly how you are linking. I'm guessing that Tcl is defining your function to have __declspec(dllexport) (assuming you've not defined STATIC_BUILD, which absolutely should not be used when building a DLL) and yet that's not getting respected. Assuming you're using a modern-enough version of GCC… which you probably are.
I'm also going through the process of how to build tcl extensions in C and had exactly the same problem when working though this same example using tcl 8.6.
i.e. I was compiling using MinGW GCC (64-bit), and used the following:
gcc -shared -o hello.dll -DUSE_TCL_STUBS "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\lib" -ltclstub86
And like the OP I got no compile error, but when loading the dll at a tclsh prompt tcl complained :
'cannot find symbol "Hello_Init"'
I can't say that I understand, but I was able to find a solution that works thanks to some trial and error, and some information on the tcl wiki here
https://wiki.tcl-lang.org/page/Building+Tcl+DLL%27s+for+Windows
In my case I had to adjust the compiler statement to the following
gcc -shared -o hello.dll hello.c "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\bin" -ltcl86t
Obviously those file paths are specific to my system, but basically
I had to add an explicit reference to the .c file
I had to include the tcl86t dll library from the tcl bin directory
I had to remove the -DUSE_TCL_STUBS flag ( meaning that the references -LC:\\ActiveTcl\\lib and -ltclstub86 could also be removed)
(attempting to use the -DUSE_TCL_STUBS flag caused the compiler to complain with C:\ActiveTcl\lib/tclstub86.lib: error adding symbols: File format not recognized )
This successfully compiled a dll that I could load, and then call the hello function to print my 'Hello World' message.
Something else I stumbled over, and which wasn't immediately obvious:
reading https://www.tcl.tk/man/tcl8.6/TclCmd/load.htm, tcl epxects to find an 'init' function based on a certain naming convention.
if the C extension does not define a package name then the name of that init function will be derived from the dll filename.
This caused a few problems for me (when compiling via Eclipse IDE), as the dll name was being automatically determined from the eclipse projet name.
For example, if I recompile the same example, but call the .dll something else, eg.
gcc -shared -o helloWorldExenstion.dll hello.c "-IC:\\ActiveTcl\\include" "-LC:\\ActiveTcl\\bin" -ltcl86t
Then at tclsh prompt:
% load helloWorldExtension
cannot find symbol "Helloworldextension_Init"
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'm trying to compile a simple "hello world"
file_name
#include <stdio.h>
void main () {
printf ("Hello World\n");
}
then I try: gcc file_name and I get "File not recognized. File format not recognized"
I however am 100% sure I did the exact same thing a few weeks back (just to see if it works, as now) and it worked, so I just don't get it.
gcc -ver // returns 4.6.1 if this helpes
Also how is gcc -o supposed to work ? The manual (man gcc) is just gibberish at times (for me)
Let's say you program is saved as helloworld.c. Typing gcc -o myprog helloworld.c would compile helloworld.c into myprog. That way, when you want to run the program, all you type in the command line is ./myprog
gcc tries to guess the language used (e.g. C or C++) based on the extension of the file, so you need to ensure you have the proper file extension (usually .cpp for C++ and .c for C dource files). Alternatively, read the manual if there is a command line option to explicitly state the format (regardless of the extension).
As for the "-o" command line parameter: the name specified after that option is the name of the object file created from the compiled source file. The object files are then linked together to form an executable