don't understand the difference between "gcc -c file.c" and "gcc -o file.c" command - linux

Command :
`gcc -c -Wall hello.c`
Here is the error : while calling ./hello.o
bash: ./hello.o: cannot execute binary file: Exec format error
need help please ..

.o is an object file, not an executable. It's an intermediate step. The -c option just says to make that step. You'll still have to link that object file into an executable.

These are the options you are asking for
-c
Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
By default, the object file name for a source file is made by replacing the suffix ‘.c’, ‘.i’, ‘.s’, etc., with ‘.o’.
Unrecognized input files, not requiring compilation or assembly, are ignored.
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.
Using the first option you will have an object file, not an executable so you cannot execute it

Related

How is the -fprofile-prefix-path option supposed to work?

When compiling code for coverage instrumentation (to use with lcov later on), we're compiling from a base directory tree (let's call it A), and we want the .gcda files to be produced at a different place (because the target directory tree is different - let's call it B).
So, the compilation command looked like this:
gcc -O0 -g --coverage -fprofile-dir=B -c -fPIC -Wall -o A/otherpath/to/mySourceFile.o A/path/to/mySourceFile.c
When checking the contents of mySourceFile.o (with the strings command), I saw that the mySourceFile.gcda file was set to be generated in B/A/otherpath/to/mySourceFile.gcda
Which is the mangling of the path given through the -fprofile-dir option with the exact absolute path of the object file created - just as written in the documentation. So far, no problem - except that what I want would be the mySourceFile.gcda file to be generated from the B directory, WITHOUT the A part.
So, the documentation also mentions the -fprofile-prefix-path option, which is supposed to allow you to remove part of the path, so that the mangling doesn't add the old path to the new.
I tried using it in the following way:
gcc -O0 -g --coverage -fprofile-dir=B -fprofile-prefix-path=A -c -fPIC -Wall -o A/otherpath/to/mySourceFile.o A/path/to/mySourceFile.c
However, after checking through strings, once again, in the generated object file, the path was still B/A/otherpath/to/mySourceFile.gcda, whereas I expected it to be B/otherpath/to/mySourceFile.gcda (that is, I expected the A part to have been stripped by the -fprofile-prefix-path option.)
Obviously, it didn't work. Any insight why ?
( Compiler used is GCC 11.2.1, which is a version recent enough to know about the option. )
Ok, after some tinkering, I got results. Maybe not exactly what I was expecting, but close enough.
Let me start by saying that the A and B "directories" I mentioned in my question were absolute paths. And it didn't work well.
However, while keeping the absolute B (target) path, I tried not using the full A (source) path while compiling. More precisely, I didn't use it to specify the OUTPUT file name, for the object. Instead, I went to the base directory (the A path), and then, ran the command by specifying the output file path relative to the current (A) directory
Which would give the following command:
(From directory A)
gcc -O0 -g --coverage -fprofile-dir=B -fprofile-prefix-path=A -c -fPIC -Wall -o otherpath/to/mySourceFile.o path/to/mySourceFile.c
This time, the source command did show an interesting result, for the mySourceFile.gcda file:
B#otherpath#to#mySourceFile.gcda
As you can see, it's not exactly what I wanted (there are # instead of /), but mentions to A disappeared, and overall, I'm confident it should work as intended. Not utterly sure yet (I still have to test it on the target platform, which will need tinkering with the way the makefiles currently work), but confident nonetheless.
Also, if I didn't use the -fprofile-prefix-path in the command, then the string would mention the A path, like this (with the '/' inside the A path being replaced with '#' characters, obviously):
B#A#otherpath#to#mySourceFile.gcda
So, the option works, but only when using relative paths, not when using absolute ones, for the object file. Hope that helps people.
PS: I checked by changing the path to the source (.c) file. Whether specified using absolute, or relative, paths, it didn't change the outcome. What matters is specifying the path to the object file in a relative manner.

How to creat only object file without executable?

I am trying to create an object file through a make file which will be called in another script.
The following is my make file for creating an object file.
SOURCE_CK = ../SOURCES_COUNTERFLOW/
SOURCES_f77 = $(SOURCE_CK)density.f
#TARGET =
OBJECTS = $(SOURCES_f77:.f=.o)
COMPILE = f77
.f.o :
$(COMPILE) -o $*.o -c $*.f
#$(TARGET) : $(OBJECTS)
# $(COMPILE) $(OBJECTS) -o $#
#del :
# /bin/rm $(OBJECTS)
When I run the above script, the following error gets generated.
make: *** No targets. Stop.
Now I know I have to make some modification with TARGET but not sure where to start or how to modify the target.
Again, my goal is to run the script and generate density.o file.
Any help would be appreciated.
GNU Make has built-in rules for making fortran object files from sources, and fortran programs from object files, see https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
Your makefile can therefore be condensed into just the following:
$(TARGET): $(OBJECTS)
Should you want to generate just the object, you can even do that without a makefile:
# make density.o from a sourcefile
make density.o
Note the built-in rules put the object files next to the source files (unless using VPATH etc etc, more about that in the manual), so you'd call it like
make ../SOURCES_COUNTERFLOW/density.o

Executable file does not exist after compiling Fortran code

I am compiling using cmake. I am on Linux with an intel processor. The important cmake lines are
set(SRCS srcA.FOR srcB.FOR ... srcK.FOR)
add_executable(filename ${SRCS})
I get no errors, just warnings. There are three types of warnings:
I am not using a variable (bad on my part but surely not code-breaking)
"this name has not been given a specific type"
"no action performed for file 'path/to/file/filename.FOR.o'"
Right before the "no action..." warning it says
Linking Fortran executable filename
and the last line says
Built target filename
That last line in particular to me implies that there should be an executable file, but I cannot find it. I have tried searching for it using
find -type f -name "*.exe" and `find -type f -name "filename" and neither are returning anything.
I will note that I am new to compiling these types of files on Linux, so I am sure there is something small I am doing wrong and don't know what it is
EDIT Added more detailed error output
Note that the "no action performed..." error appears once for each file and is identical (besides the filename of course)
ifort: warning #10145: no action performed for file 'CMakeFiles/dynamicmpm.dir/getversion.for.o'
EDIT #2 Adding the contents of the cmake file below
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(MPM)
enable_language (Fortran)
get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)
MESSAGE("Fortran_COMPILER_NAME = ${Fortran_COMPILER_NAME}")
set(CMAKE_Fortran_FLAGS "-nologo -O2 -assume buffered_io -fpp -Dinternal_release -reentrancy threaded -free -warn all -real_size 64 -Qauto -fp:strict -fp:constant -libs:static -threads -Qmkl:sequential -c -Qm64")
if (Fortran_COMPILER_NAME MATCHES "gfortran")
# gfortran
set(COMMON_FLAGS "-fmax-identifier-length=63 -ffree-form -ffree-line-length-none -fdefault-real-8")
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} ${COMMON_FLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${COMMON_FLAGS}")
endif()
set(SRCS srcA.FOR srcB.FOR ... srcK.FOR) #theres a bazillion files so I made this dummy line for the post
add_executable(filename ${SRCS})
EDIT 3
I get the following error now after making the changes recommended below:
[100%] Linking Fortran executable dynamicmpm
CMakeFiles/dynamicmpm.dir/Solver.FOR.o: In function `modsolver_mp_createprofiledss_':
Solver.FOR:(.text+0x1143): undefined reference to `dss_create_'
Solver.FOR:(.text+0x11a8): undefined reference to `dss_define_structure_'
Solver.FOR:(.text+0x1471): undefined reference to `dss_reorder_'
CMakeFiles/dynamicmpm.dir/Solver.FOR.o: In function `modsolver_mp_solveequations_':
Solver.FOR:(.text+0x35ec): undefined reference to `dss_factor_real_d__'
Solver.FOR:(.text+0x361d): undefined reference to `dss_solve_real_d_'
CMakeFiles/dynamicmpm.dir/Solver.FOR.o: In function `modsolver_mp_destroyequations_':
Solver.FOR:(.text+0x4495): undefined reference to `dss_delete_'
CMakeFiles/dynamicmpm.dir/Solver.FOR.o: In function `modsolver_mp_initialisereducedsolution_':
Solver.FOR:(.text+0x5a58): undefined reference to `dss_create_'
Solver.FOR:(.text+0x5abd): undefined reference to `dss_define_structure_'
Solver.FOR:(.text+0x606d): undefined reference to `dss_reorder_'
at the top of Solver.FOR I have use mkl_dss and mkl_dss.f90 is included in
set(SRCS srcA.FOR srcB.for mkl_dss.f90 ... otherSources.FOR)
Am I linking the files incorrectly?
no action performed for file 'path/to/file/filename.FOR.o' - You passed -c to flags, so compiler does not know what to do with object files. Research what -c flag means. Remove -c flag.
get_filename_component (Fortran_COMPILER_NAME - use CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" instead.
Do not use set(CMAKE_Fortran_FLAGS. Prefer target_compiler_options, target_link_options, target_link_libraries or add_compile_options instead.
Do not write long lines. Split them with newlines as a list.
set(COMMON_FLAGS - if they are common, why add them to _RELEASE and _DEBUG separately? Just add_compile_options them.

Can not find object file with cmake link_directories

I want to add several .o files to the link process. If I do it like this:
TARGET_LINK_LIBRARIES(FFMPEGTest stdc++fs -pthread /home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/audioconvert.o ...some more stuff... )
then it finds the file. All of these files are in the same directory, so I want to add them semultaneously:
link_directories(/home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/)
TARGET_LINK_LIBRARIES(FFMPEGTest stdc++fs -pthread audioconvert.o ...some more stuff... )
but this doesn't work:
/usr/bin/ld: cannot find -laudioconvert.o
how do I fix this?
Documentation for target_link_libraries doesn't allow a relative path (audioconvert.o) to be a parameter to that command. It should be either absolute path (/home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/audioconvert.o) or a plain library name (like z for libz.a library).
Because the object file audioconvert.o is not a library, it cannot be specified with a plain library name. You have no other choice than specify an absolute path for the object files.
For specify several object files in some directory you may use foreach loop:
foreach(obj audioconvert.o foo.o bar.o)
target_link_libraries(FFMPEGTest /home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/${obj})
endforeach()
Actually, every parameter <param> to target_link_libraries, which doesn't look like an absolute path (and doesn't corresponds to a library target), is transformed into -l<param> option for the linker.
The linker interprets this parameter as a plain library name, and searches for a file named lib<param>.a or lib<param>.so in the link directories.
So, with parameter -laudioconvert.o the linker searches a file with a name libaudioconvert.o.a - obviously, this is not what do you want.

Windres syntax error

I am working in MinGW environment (downloaded with their installer on 12/12/2011). I am attempting to compile a resource (.rc) file using Windres. The specific command I use is
Windres -O coff About1.rc -o About1.res
Windres generates at least 100 lines of warning messages reading: "warning: null characters ignored". Following this Windres emits: "Abouty1.rc:1:syntax error".
As a matter of fact, there are no null characters in the About1.rc file. In addtition, the first line of the file is an include statement: #include "dlgresource.h". I played around and eliminated this statement and it turns out that it doesn't matter what I put there, I get the same flurry of messages and the syntax error notification.
To make things more confusing, this same .rc file compiles without any problem using MSFT's rc.exe. The resulting .res file links smoothly with the program .obj file and runs perfectly.
I have no idea what is going on. Any ideas?
Thanks,
Mark Allyn
Your .rc file is probably encoded as UTF-16.
That's what's required in general by Microsoft's [rc.exe], in order to be able to deal with international characters, but GNU [windres.exe] can only deal with ANSI encoding.
One workaround is to convert the file to ANSI on the spot (possibly losing e.g. Russian or Greek characters):
> chcp 1252
Active code page: 1252
> type my.rc | windres --output-format=COFF -o my.res
> _
You probably used VS or a similar tool to generate the file. There are some parts of the character encodings that you cannot see resulting in null characters and etc.
Generate a new .res file with the same content, don't copy/paste the content, type it in yourself.
Try:
windres About1.rc -o About1.o
and then just use the resulting .o file instead of the originally intended .res file.
I've had the same troubles than you today. I know it has passed a lot of time from your question, but I'm writting this on the hope that it can be useful for someone.
First, I obtained an object file .o compiled using Cygwin, writting:
windres -o resource.o resource.rc
By doing that, you dont need to use the .res file, but the .o one, and you can then link this object with all the others, when you compile yout program, using GNU resources:
g++ Header_files CPP_files flags ... -o program.exe recource.o -lm
For instance.

Resources