When I compiled a program on cygwin like the following
g++ -o helloworld helloworld.cpp
An executable helloworld.exe is created. However, I could not execute the program by using
./helloworld
but instead I need to use
./helloworld.exe
Is there a way to enable the cygwin to recognize helloworld as an executable for the file helloworld.exe
This isn't directly related to g++.
Windows requires executable files (of the kind generated by a compiler, not batch files) to have names with a .exe extension; that's how the OS recognizes them as executables.
Cygwin, as you know, implements a POSIX-like layer on top of Windows. POSIX systems (UNIX, Linux, et al) do not require any special suffix for executable files; the OS recognizes a file as executable based on a "magic number" in the file itself and the executable bit in its directory entry.
To bridge this gap, Cygwin treats the .exe extension separately. Compilers like g++ generate executable files with the .exe suffix, but Cygwin lets you execute a file named helloworld.exe by typing either ./helloworld.exe or ./helloworld. (This even applies to other operations; ls -l helloworld will show you information about helloworld.exe -- assuming there's not also a file named just helloworld.)
In this case, based in information you've provided in the comments, you apparently have two executable files in your current directory, helloworld.exe and helloworld.
I'm not 100% sure what Cygwin will do in this case, but the solution is to delete the helloworld file and make sure that your executables have the required .exe extension. Cygwin compilers will do this for you by default; even if you run
g++ helloworld.cpp -o helloworld
it will generate an executable file named helloworld.exe.
I don't know what you did to create an executable file without the .exe extension. Whatever it was, don't do it again.
Related
I have started looking into the concepts of linking libraries with exes and working in Linux machine. I'm struggling to understand the concept of linking so files with executables.
app:$(CC) $(CFLAGS) $(LDFLAGS) app.o app_dep.o -L . -ldynamic -Wl,-rpath . \
-o app
I'm trying to create an executable app with the above lines in makefile. I have to link it with a libdynamic.so file which exists in the working directory. So i used -L flag and -rpath to point to the directory and name of the so file. It worked and executable is created.
But when i tried to run the executable, it again complains that libdynamic.so: cannot open shared object file: No such file or directory.
Why do i need it since i linked the sharedlibrary during the creation of executable itself?
If the answer to the question is "Yes, it is required to point to the lib even it is linked". How could i point to the folder where it presents during the execution of binary?
One way i found is using LD_LIBRARY_PATH environment variable. Is there any other way to do without environment variable?
Thanks
Why do i need it since i linked the sharedlibrary during the creation of executable itself?
Because linking against a shared library does not embed that shared library into the executable. That is the main difference between linking with a shared versus archive library.
How could i point to the folder where it presents during the execution of binary?
There are no "folders" in UNIX. They are directories.
The correct link command to make an executable look in current directory is:
gcc -o app app.o ... -L. -ldynamic -Wl,-rpath=.
Note that in general it's a really bad idea to do so: your executable will or will not run depending on your current directory (or it may use different versions of libdynamic.so depending on which directory you are in).
Your link command should have worked if you invoked app in the directory with libdynamic.so present (i.e. if you invoked it like ./app), but not if you used /path/to/app (and were not in the same directory).
A significantly better approach is to do this:
gcc -o app app.o ... -L. -ldynamic -Wl,-rpath='$ORIGIN'
That tells the app binary to look for libdynamic.so in the same directory in which app is located, regardless of your current directory.
I'm currently trying to start learning ocaml with cygwin, but when I try to compile an ml file, nothing happens - no error messages and no files created.
The command I used on cygwin was,
$ ocamlc hello.ml
According to my Prof., there should be a file called, a.out created on my working folder, but there was nothing.
But when I tried with this command,
$ ocamlc -o a.out hello.ml
a.out file was created properly, and I could run the compiled program using
$ ./a.out
as pointed out by the Prof.
For some experiment, I typed in the following,
$ ocamlc -o a hello.ml
This created a file named 'a' without any file extension.
So my question is,
1. Why doesn't it create the a.out file in the first place? - it should have been done according to the Prof.
2. What does the .out file do?
Any new file created when you type ocamlc hello.ml? Maybe camlprog.exe around? If it is, you are using MinGW OCaml over Cygwin. MinGW OCaml is a windows app therefore its default executable file name is not a.out, which is the default name for Unix and Cygwin.
I never recommend ppl to learn OCaml with Windows or Cygwin. Since there are 3 flavors: Cygwin OCaml, MinGW OCaml and MSVC OCaml and they behave slightly different like this. And newcomers are never sure which flavor they are actually using.
My project includes a library and example projects for how to use it. I place the library in the "bin" folder along with all executable examples. I can run the example projects on the machine where they were compiled but when I try to run them on another machine I get:
./example: error while loading shared libraries: libMyLib.so: cannot
open shared object file: No such file or directory
This makes no sense since the library is in the same folder. What is causes it to ignore the library on other machines?
Just because the library is in the same directory as the executable doesn't mean it will look there for it. By default on linux, executables will only look in a limited set of directories, set by ldconfig and the LD_LIBRARY_PATH environment variable.
One trick that is very useful is to link your program with the extra linker option
-Wl,-rpath,'$ORIGIN'
which will cause the executable to also look in the directory the executable is in for shared objects.
You can usually set this by adding to your Makefile:
LDFLAGS := -Wl,-rpath,'$$ORIGIN'
Note the double-$ here -- make will interpret this as a make variable which expands to just $
The current directory is not necessarily a place where the dynamic linker will look for dynamic libraries. The directory where the executable is much less.
You might want to check ldconfig to see where it looks for them.
I'm new in Linux. I have a library in a folder next to my C program source but I don't know how to compile it. I've compiled everything when my library was in the same folder as program code file. However, I do not understand how to use the library from another location?
Use gcc's -L option to specify where your library located, and -l option to specify what your library is.
If you're using 'make' to build your program, just open the Makefile and find out where -L option has used.
For example,
gcc -L ./my_program/my_library -lmylib -o my_executable ./my_program/src/my_program.c
Also, you can use LD_LIBRARY_PATH environment variable to specify your library path to your program.
Say that you have ready to run your excutable, but the library is not in any standard library path (such as /usr/lib),
then you can run your program by following command.
$ LD_LIBRARY_PATH=/home/my_name/my_program/my_library my_executable
Is it possible to set such a build command in it, which will compile source via cygwin call?
The default command in preferences is gcc -Wall -o "%e" "%f" which calls MinGW, but some files can be compiled with cygwin version of gcc only (those which have linux specific libs like termios.h etc).
I tried this c:\cygwin\bin\bash -c "gcc -Wall -o %e %f", it works just like the default line, it again doesn't build those files with linux libs.
It'd probably work alright if you set the command to:
C:/cygwin/bin/gcc -Wall -o %e %f
According to some documentation, Cygwin imports Windows environment variables, so even launching gcc from within Cygwin bash it might still find the wrong gcc (ie. MinGW one) due to Windows PATH environment variable. Here's a blurb from those docs:
The PATH environment variable is used by Cygwin applications as a list of directories to search for executable files to run. This environment variable is converted from Windows format (e.g. C:\Windows\system32;C:\Windows) to UNIX format (e.g., /cygdrive/c/Windows/system32:/cygdrive/c/Windows) when a Cygwin process first starts...
You might need to tinker with the linker's library search paths (ex. LD_LIBRARY_PATH) and gcc include directories too.