📄 how-programming.texinfo
字号:
net release.)}Pass heap/stack linker arguments to gcc. To create foo.exe witha heap size of 1024 and a stack size of 4096, you would invokegcc as:@code{gcc -Wl,--heap,1024,--stack,4096 -o foo foo.c}@subsection How can I find out which dlls are needed by an executable?@samp{objdump -p} provides this information, but is rather verbose.@samp{cygcheck} will do this much more concisely, and operatesrecursively, provided the command is in your path.Note there is currently a bug in cygcheck in that it will not reporton a program in a Windows system dir (e.g., C:\Windows or C:\WINNT) evenif it's in your path. To work around this, supply the full Win32 pathto the executable, including the .exe extension:@examplecygcheck c:\\winnt\\system32\\cmd.exe@end example(Note the windows path separator must be escaped if this is typed inbash.)@subsection How do I build a DLL?@strong{(Please note: This section has not yet been updated for the latestnet release.)}There's documentation that explains the process on the main Cygwinproject web page (http://cygwin.com/).@subsection How can I set a breakpoint at MainCRTStartup?@strong{(Please note: This section has not yet been updated for the latestnet release.)}Set a breakpoint at *0x401000 in gdb and then run the program inquestion.@subsection How can I build a relocatable dll?@strong{(Please note: This section has not yet been updated for thelatest net release. However, there was a discussion on the cygwinmailing list recently that addresses this issue. Read@file{http://cygwin.com/ml/cygwin/2000-06/msg00688.html} andrelated messages.)}You must execute the following sequence of five commands, in thisorder:@example$(LD) -s --base-file BASEFILE --dll -o DLLNAME OBJS LIBS -e ENTRY$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE \ --base-file BASEFILE --output-exp EXPFILE$(LD) -s --base-file BASEFILE EXPFILE -dll -o DLLNAME OBJS LIBS -e ENTRY$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE \ --base-file BASEFILE --output-exp EXPFILE$(LD) EXPFILE --dll -o DLLNAME OBJS LIBS -e ENTRY@end exampleIn this example, $(LD) is the linker, ld.$(DLLTOOL) is dlltool.$(AS) is the assembler, as.DLLNAME is the name of the DLL you want to create, e.g., tcl80.dll.OBJS is the list of object files you want to put into the DLL.LIBS is the list of libraries you want to link the DLL against. Forexample, you may or may not want -lcygwin. You may want -lkernel32.Tcl links against -lcygwin -ladvapi32 -luser32 -lgdi32 -lcomdlg32-lkernel32.DEFFILE is the name of your definitions file. A simple DEFFILE wouldconsist of ``EXPORTS'' followed by a list of all symbols which shouldbe exported from the DLL. Each symbol should be on a line by itself.Other programs will only be able to access the listed symbols.BASEFILE is a temporary file that is used during this five stageprocess, e.g., tcl.base.EXPFILE is another temporary file, e.g., tcl.exp.ENTRY is the name of the function which you want to use as the entrypoint. This function should be defined using the WINAPI attribute,and should take three arguments: int WINAPI startup (HINSTANCE, DWORD, LPVOID)This means that the actual symbol name will have an appended @@12, so ifyour entry point really is named @samp{startup}, the string you shoulduse for ENTRY in the above examples would be @samp{startup@@12}.If your DLL calls any Cygwin API functions, the entry function will needto initialize the Cygwin impure pointer. You can do that by declaringa global variable @samp{_impure_ptr}, and then initializing it in theentry function. Be careful not to export the global variable@samp{_impure_ptr} from your DLL; that is, do not put it in DEFFILE.@example/* This is a global variable. */struct _reent *_impure_ptr;extern struct _reent *__imp_reent_data;int entry (HINSTANT hinst, DWORD reason, LPVOID reserved)@{ _impure_ptr = __imp_reent_data; /* Whatever else you want to do. */@}@end exampleYou may put an optional `--subsystem windows' on the $(LD) lines. TheTcl build does this, but I admit that I no longer remember whetherthis is important. Note that if you specify a --subsytem <x> flag to ld,the -e entry must come after the subsystem flag, since the subsystem flagsets a different default entry point.You may put an optional `--image-base BASEADDR' on the $(LD) lines.This will set the default image base. Programs using this DLL willstart up a bit faster if each DLL occupies a different portion of theaddress space. Each DLL starts at the image base, and continues forwhatever size it occupies.Now that you've built your DLL, you may want to build a library sothat other programs can link against it. This is not required: youcould always use the DLL via LoadLibrary. However, if you want to beable to link directly against the DLL, you need to create a library.Do that like this:$(DLLTOOL) --as=$(AS) --dllname DLLNAME --def DEFFILE --output-lib LIBFILE$(DLLTOOL), $(AS), DLLNAME, and DEFFILE are the same as above. Makesure you use the same DLLNAME and DEFFILE, or things won't work right.LIBFILE is the name of the library you want to create, e.g.,libtcl80.a. You can then link against that library using somethinglike -ltcl80 in your linker command.@subsection How can I debug what's going on?You can debug your application using @code{gdb}. Make sure youcompile it with the -g flag! If your application calls functions inMS dlls, gdb will complain about not being able to load debug informationfor them when you run your program. This is normal since these dllsdon't contain debugging information (and even if they did, that debuginfo would not be compatible with gdb).@subsection Can I use a system trace mechanism instead?Yes. You can use the @code{strace.exe} utility to run other cygwinprograms with various debug and trace messages enabled. For informationon using @code{strace}, see the Cygwin User's Guide or the file@code{winsup/utils/utils.sgml}.@subsection Why doesn't gdb handle signals?Unfortunately, there is only minimal signal handling support in gdbcurrently. Signal handling only works with Windows-type signals.SIGINT may work, SIGFPE may work, SIGSEGV definitely does. You cannot'stop', 'print' or 'nopass' signals like SIGUSR1 or SIGHUP to theprocess being debugged.@subsection The linker complains that it can't find something.@strong{(Please note: This section has not yet been updated for the latestnet release.)}A common error is to put the library on the command line beforethe thing that needs things from it.This is wrong @code{gcc -lstdc++ hello.cc}.This is right @code{gcc hello.cc -lstdc++}.@subsection I use a function I know is in the API, but I still get a link error.@strong{(Please note: This section has not yet been updated for the latestnet release.)}The function probably isn't declared in the header files, orthe UNICODE stuff for it isn't filled in.@subsection Can you make DLLs that are linked against libc ?@strong{(Please note: This section has not yet been updated for the latestnet release.)}Yes.@subsection Where is malloc.h?@strong{(Please note: This section has not yet been updated for the latestnet release.)}Include stdlib.h instead of malloc.h.@subsection Can I use my own malloc?If you define a function called @code{malloc} in your own code, and linkwith the DLL, the DLL @emph{will} call your @code{malloc}. Needless tosay, you will run into serious problems if your malloc is buggy.If you run any programs from the DOS command prompt, rather than from inbash, the DLL will try and expand the wildcards on the command line.This process uses @code{malloc} @emph{before} your main line is started.If you have written your own @code{malloc} to need some initializationto occur after @code{main} is called, then this will surely break.Moreover, there is an outstanding issue with @code{_malloc_r} in@code{newlib}. This re-entrant version of @code{malloc} will be calleddirectly from within @code{newlib}, by-passing your custom version, andis probably incompatible with it. But it may not be possible to replace@code{_malloc_r} too, because @code{cygwin1.dll} does not export it andCygwin does not expect your program to replace it. This is really anewlib issue, but we are open to suggestions on how to deal with it.@subsection Can I mix objects compiled with msvc++ and gcc?Yes, but only if you are combining C object files. MSVC C++ uses adifferent mangling scheme than GNU C++, so you will have difficultiescombining C++ objects.@subsection Can I use the gdb debugger to debug programs built by VC++?No, not for full (high level source language) debugging.The Microsoft compilers generate a different type of debuggingsymbol information, which gdb does not understand.However, the low-level (assembly-type) symbols generated byMicrosoft compilers are coff, which gdb DOES understand.Therefore you should at least be able to see all of yourglobal symbols; you just won't have any information aboutdata types, line numbers, local variables etc.@subsection Where can I find info on x86 assembly?CPU reference manuals for Intel's current chips are available indownloadable PDF form on Intel's web site:@file{http://developer.intel.com/design/pro/manuals/}@subsection Shell scripts aren't running properly from my makefiles?If your scripts are in the current directory, you must have @samp{.}(dot) in your $PATH. (It is not normally there by default.) Otherwise,you would need to add /bin/sh in front of each and every shell scriptinvoked in your Makefiles.@subsection What preprocessor do I need to know about?We use _WIN32 to signify access to the Win32 API and __CYGWIN__ foraccess to the Cygwin environment provided by the dll.We chose _WIN32 because this is what Microsoft defines in VC++ andwe thought it would be a good idea for compatibility with VC++ codeto follow their example. We use _MFC_VER to indicate code that shouldbe compiled with VC++._WIN32 is only defined when you use either the -mno-cygwin or -mwin32gcc command line options. This is because Cygwin is supposed to be aUnix emulation environment and defining _WIN32 confuses some programswhich think that they have to make special concessions for a Windowsenvironment which Cygwin handles automatically.@subsection How should I port my Unix GUI to Windows?There are two basic strategies for porting Unix GUIs to Windows.The first is to use a portable graphics library such as tcl/tk, X11, orV (and others?). Typically, you will end up with a GUI on Windows thatrequires some runtime support. With tcl/tk, you'll want to include thenecessary library files and the tcl/tk DLLs. In the case of X11, you'llneed everyone using your program to have an X11 server installed.The second method is to rewrite your GUI using Win32 API calls (or MFCwith VC++). If your program is written in a fairly modular fashion, youmay still want to use Cygwin if your program contains a lot of shared(non-GUI-related) code. That way you still gain some of the portabilityadvantages inherent in using Cygwin.@subsection Why not use DJGPP ?DJGPP is a similar idea, but for DOS instead of Win32. DJGPP uses a"DOS extender" to provide a more reasonable operating interface for itsapplications. The Cygwin toolset doesn't have to do this since all ofthe applications are native WIN32. Applications compiled with theCygwin tools can access the Win32 API functions, so you can writeprograms which use the Windows GUI.You can get more info on DJGPP by following@file{http://www.delorie.com/}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -