I'm trying to build Derelict2 on Lion as per the included installation instructions. When I run the command make -fmac.mak DC=dmd the following libraries build fine:
DerelictAllegro
DerelictFMOD
DerelictFT
DerelictGL
DerelictIL
DerelictODE
DerelictOgg
DerelictPA
Unfortunately once the script gets up to DerelictSDL it spits out the following:
make -C DerelictSDL all PLATFORM=mac
dmd -release -O -inline -I../DerelictUtil -c derelict/sdl/sdl.d derelict/sdl/sdlfuncs.d derelict/sdl/sdltypes.d -Hd../import/derelict/sdl
dmd -release -O -inline -I../DerelictUtil -c derelict/sdl/macinit/CoreFoundation.d derelict/sdl/macinit/DerelictSDLMacLoader.d derelict/sdl/macinit/ID.d derelict/sdl/macinit/MacTypes.d derelict/sdl/macinit/NSApplication.d derelict/sdl/macinit/NSArray.d derelict/sdl/macinit/NSAutoreleasePool.d derelict/sdl/macinit/NSDictionary.d derelict/sdl/macinit/NSEnumerator.d derelict/sdl/macinit/NSEvent.d derelict/sdl/macinit/NSGeometry.d derelict/sdl/macinit/NSMenu.d derelict/sdl/macinit/NSMenuItem.d derelict/sdl/macinit/NSNotification.d derelict/sdl/macinit/NSObject.d derelict/sdl/macinit/NSProcessInfo.d derelict/sdl/macinit/NSString.d derelict/sdl/macinit/NSZone.d derelict/sdl/macinit/runtime.d derelict/sdl/macinit/SDLMain.d derelict/sdl/macinit/selectors.d derelict/sdl/macinit/string.d -Hd../import/derelict/sdl/macinit
derelict/sdl/macinit/NSString.d(134): Error: cannot implicitly convert expression (this.length()) of type ulong to uint
derelict/sdl/macinit/NSString.d(135): Error: cannot implicitly convert expression (str.length()) of type ulong to uint
derelict/sdl/macinit/NSString.d(140): Error: cannot implicitly convert expression (cast(ulong)(selfLen + aStringLen) - aRange.length) of type ulong to uint
make[1]: *** [dmd_mac_build_sdl] Error 1
make: *** [DerelictSDL_ALL] Error 2
The latest version of Derelict is Derelict3, which is on GitHub.
As for your error, it looks like you are compiling for 64-bit, which apparently hasn't been taken into consideration in Derelict2.
You'll just need to fix the source code. The correct way to do this would be to change those instances to use size_t instead of uint, but it might be easier just to cast(size_t) those expressions until the errors go away :-) It's unlikely that the lengths will ever be above 4 billion, so you should be fine until you switch over to Derelict3.
Try to compile in 32 bit mode. I believe it is the -m32 option for dmd and gdc/gdmd
Related
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'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 have turned on the ld option --fatal-warning in the linux kernel. How can I generate a simple linker warning to test this feature?
#include<stdio.h>
int main()
{
printf("Run !!");
static const char warning[] __attribute__((section(".gnu.warning.printf")))="My sweet linker warning";
return 0;
}
Save this as test.c
If you build this using:
gcc -Wl,--fatal-warnings test.c -o my_exe
You should receive your linker warning and it would not prepare "my_exe"
Now try:
gcc -Wl,--no-fatal-warnings test.c -o my_exe
In this case, warning will be reported as it is but it wont be treated as error and it will prepare "my_exe" for you.
I am not sure what exactly you meant by "turned on", but if you are seeing above behavior then I guess you are good.
If you are doing something with kernel source then you will need to replace printf with any function name you already have in source( also change .gnu.warning section name )
Thank you all for your suggestions. I went through the makefile, and found some linker flags that were suppressing warnings. I just removed them to generate ld warnings.
In Xcode can I use ## in a macro?
In MSVC I can write:
#define FOO(_var) int foo##_var## = 1
FOO(bar);
foobar++;
On the Mac (edit: compiling with GCC) the same code gives me the error "Pasting "foobar" and "=" does not give a valid preprocessing token. Is ## not supported in xcode?
Concatenation is supported in GCC and Clang. Xcode isn't a compiler; if you're posting errors like this, check what version of GCC, LLVM-GCC or Clang ("LLVM compiler") you're using because their behavior can differ.
You're trying to make = part of an identifier (i.e., create a variable called foobar=) which I don't think is what you want.
Try #define FOO(_var) int foo##_var = 1 instead.
Incidentally, Clang gives a somewhat better error message:
foo.c:4:5: error: pasting formed 'foobar=', an invalid preprocessing token
FOO(bar);
^
foo.c:1:32: note: instantiated from:
#define FOO(_var) int foo##_var## = 1
^