I'm writing firmware using an older C compiler called HC12. Currently I use GNU Make for the build system. I'm hoping to start using CMake, but ran into an issue:
The compiler does not support some standard C compiler syntax, namely the "-o" flag.
I've made a custom toolchain file and added all my c flags, but CMake seems to implicitly add the "-o" to compile source files, in the generated GNU Makefiles.
The HC12 compiler allows me to use -objn="name_of_file" to specify the output filename.
My question: Is there a way to get CMake to stop putting the implicit "-o" so that I can use this compiler?
I know there is a GCC port for this processor, but changing compilers at this point isn't an option.
You could take a file like the Modules/Compiler/ti.cmake as a reference and create one for your HC12 compiler, and also change these macros defined there:
# the input file options from TI, change to what your compiler needs
# They are used below in the command where ${lang} is either C, CXX or ASM
set(__COMPILER_HC12C_SOURCE_FLAG_C "--c_file")
set(__COMPILER_HC12C_SOURCE_FLAG_CXX "--cpp_file")
set(__COMPILER_HC12C_SOURCE_FLAG_ASM "--asm_file")
# add output file option
set(__COMPILER_HC12C_OUTPUT_FLAG_C "--objn")
macro(__compiler_HC12C lang)
# ...
set(CMAKE_${lang}_COMPILE_OBJECT "<CMAKE_${lang}_COMPILER> --compile_only ${__COMPILER_HC12C_SOURCE_FLAG_${lang}}=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> ${__COMPILER_HC12C_OUTPUT_FLAG_${lang}}=<OBJECT>")
# --------------------------------------- ---------------------------------------
# ...
endmacro()
Hope, this will help.
Related
I have a stm32f103 project that is initialized using stm32cubemx and I'm using neovim for editing and arm-none-eabi-gcc for compilation of code (whit auto-generated makefile).
I also have installed clangd LSP and also bear to generate compile_commands.json file. Everyting works fine except that there's two errors:
stdio.h file not found
Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)
I looked at core_cm3.h file and __FPU_USED is disabled, which is exactly what clang says.
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
But I couldn't find any line in my makefile flags that enables the FPU for compilation.
# fpu
# NONE for Cortex-M0/M0+/M3
# float-abi
# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
I also commented out $(FPU) and $(FLOAT-ABI), but the error still exists.
Although I can compile the project without any problems (because gcc has no complaints), but these errors are kind of on my nerve.
Is there a way to fix these errors? Or is there any gcc-based LSPs to use instead of clangd?
There's also ccls on neovim's LSP list but I was unable to install it.
s there a way to fix these errors?
https://clangd.llvm.org/config#files You can:
create clangd configuration file
specify -sysroot command to specify the location of your buildchain (/usr/arm-none-eabi/ on my system)
and other needed options (-isysroot -nostdlib etc.) if you use them.
I would advise anyway to move CMake and generate compile_command.json anyway.
is there any gcc-based LSPs to use instead of clangd?
I am not aware of any.
Using command clang -### a.c can output the commands that clang a.c calls.
For me, it outputs followings on my screen(focus on last three lines):
clang version 1.0 (https://llvm.org/svn/llvm-project/cfe/branches/release_26 exported)
Target: x86_64-unknown-linux-gnu
Thread model: posix
"/usr/local/bin/llvm+clang-2.6-x86_64-linux/bin/../libexec/clang-cc" "-triple" "x86_64-unknown-linux-gnu" "-S" "-disable-free" "-main-file-name" "a.c" "--relocation-model" "static" "--disable-fp-elim" "--unwind-tables=1" "--mcpu=x86-64" "--fmath-errno=1" "-fdiagnostics-show-option" "-o" "/tmp/cc-yffqSv.s" "-x" "c" "a.c"
"/usr/bin/gcc" "-c" "-m64" "-o" "/tmp/cc-pa2Qo4.o" "-x" "assembler" "/tmp/cc-yffqSv.s"
"/usr/bin/gcc" "-m64" "-o" "a.out" "/tmp/cc-pa2Qo4.o"
In the line: /usr/local/bin/llvm+clang-2.6-x86_64-linux/bin/../libexec/clang-cc" "-triple" "x86 ......, it shows that the command clang called this: /libexec/clang-cc.
What does it(file "libexec/clang-cc") do?
And there is another question related I desired to ask:
Whether or not: command clang uses the front end of the project "clang", and the back end of "gcc"?
Because I find the last two line of code above called "/usr/bin/gcc".
I have search this for hours, can you help me?
Thanks in advance.
You seem to be using quite an old version of Clang. You might want to try a newer one.
clang-cc is the clang C compiler, which converts a C program to assembly language. [Note 1]. Depending on version and target, it may also be able to directly produce an object file. See the -integrated-as command-line flag.
If your version of Clang does not have an assembler for your target architecture, the clang driver will try to use the system assembler (and linker). On some systems, these will be part of Gcc, although there are other options.
Notes
Clang actually first compiles C (or other C-like languages) into platform-neutral LLVM Intermediate Representation (IR), and then uses the LLVM library to convert that into optimised platform-specific assembler code. These two parts are what are generally referred to as the Clang "front-end" (C⇒LLVM) and "back-end" (LLVM⇒Assembler). These are not separate programs
What does it(file "libexec/clang-cc") do?
Its output "-o" "/tmp/cc-yffqSv.s" suggests it outputs assembly.
and the back end of "gcc"?
The last two lines with gcc invocations are:
Generate an object file from the assembly.
Link object files into a.out.
I have already known that the GCC's argument -finstrument-functions can hook the functions and the argument -finstrument-functions-exclude-file(functions)-list can exclude some files/functions to be traced.
But now I have a lot of files to be compiled and only some of them need to be traced. I wonder if I can include some specific functions/files to be traced, such as something like -finstrument-functions-include-file(functions)-list?
Thanks a lot!
GCC does not support this out-of-the-box (it's more a task for your build system). One common hack to achieve what you want is to write a shell wrapper which replaces GCC and adds flags where needed:
$ cat path/to/fake/gcc
#!/bin/sh
FLAGS=
if echo "$*" | grep -q 'myfile1.c'; then
FLAGS=-finstrument-functions
fi
exec /usr/bin/gcc "$#" $FLAGS
$ export PATH="path/to/fake:$PATH"
If you use cmake to build your project you may benefit from adding COMPILE_OPTIONS at a specific level. Use
add_compile_options()
for directory-wide settings
target_compile_options()
for target-specific settings and
set_source_files_properties()
for file specific settings.
In your case
set_source_files_properties(
myfile1.cc PROPERTIES COMPILE_FLAGS -finstrument-functions)
Recent GCC compilers can be extended by GCC plugins.
But now I have a lot of files to be compiled and only some of them need to be traced.
You should consider writing your own GCC plugin to do that job. See also this draft report.
You may configure your build automation tool (e.g. GNU make or ninja) to help you.
At last, some of your C code (e.g. #include-ed files) could be generated. Think of meta-programming approaches (e.g. with SWIG or ANTLR or Bison or GPP or your own C code generator), perhaps using X-macros.
For a project I need to find if a c file has code that requires >=C11 or C99 compiler. Can this be done with gcc, or ctags?
Basically I need to identify the minimum version of compiler required to compile the file. I have tried different tools including ctags etc.
Use grep -- -std= Makefile
ctags: no way
If you are looking for something smarter... bad luck.
I was using Fortran g77 and experienced this problem:
c this program calculates runoff and sediment
1 2
Unrecognized statement name at (1) and invalid form for assignment or statement-function definition at (2)
Also, the compiler can recognized only .for file extension, not .f.
Does anyone know, where is the problem? I downloaded it from http://www.cse.yorku.ca/~roumani/fortran/ftn.htm.
The compiler is not recognizing that statement as a comment. As a comment it should ignore the line but it is trying parse it. Are you sure that the "C" is in the first column?
Why are you using g77? It hasn't been supported for years. gfortran is the current GNU Fortran compiler. It can compile FORTRAN 77, Fortran 90, 95 and portions of 2003 and 2008.
EDIT: Perhaps its wants an upper-case "C".
The page you have linked to states that the f2exe wrapper passes -ffree-form to the compiler:
Compilation Command
The above f2exe command is just a batch file that invokes g77, the "real" compilation command. The command:
g77 -ffree-form prog.for -oprog.exe
directs the compiler to compile the file prog.for and stores the output in the file prog.exe. The -ffree-form switch indicates free-form style (remove it if you are using the old style).
In free-form Fortran the only allowed comment format is that of a line starting with !. As a matter of fact, this is also written on the same page directly under the above text:
Comments
In free-form style, use ! for both full-line and in-line comments. In the old style, use a "C" in column-1.
If you are not using the provided f2exe wrapper, don't pass -ffree-form option when compiling fixed-form FORTRAN 77 code.
I'll assume you want to stick with this compiler.
As noted above, the problems you have come from using the F2EXE batch file, which is not very useful: first it automatically adds ".for" to the file name, so you can't compile ".f" files, and it assumes free-form syntax, which is unusual when programming in Fortran 77 (and if you want Fortran 90, find another compiler, other answers give you links).
Now, suppose you have written a program myprogram.f, and you are in a Windows command line, in the same directory where the program resides (use "cd C:\mydirectory" for example, to change)
You will compile with
g77 myprogram.f
If you use SLATEC, you use
g77 myprogram.f -lslatec
If you want to specify a name for your .exe file (default is a.exe), you write
g77 myprogram.f -o myprogram.exe
There are other useful options
g77 -O2 myprogram.f to optimize (within g77 2.95 limitations)
g77 -Wall myprogram.f to enable all compiler warnings, very useful
to find errors in your code
g77 -c myprogram.f to only compile (you get a .o file), this is
useful to compile functions and subroutines, to
later build a static library (.a file), like
libslatec.a which is given with the compiler
And to build a library, using ar.exe:
ar cru mylib.a myfunc1.o myfnuc2.o ...
Then you can use is with
g77 myprogram.f mylib.a
G77 runs in command line under Windows. You write programs in a text editor.
Notepad++ is fairly good and its free. See http://notepad-plus-plus.org/
If you have problems with compilation, maybe it comes from environment variables, so here are some precisions. You have to tell Windows where to find the G77 compiler (g77.exe).
You can follow instructions on the site where you downloaded it to change Windows' environment variables PATH and LIBRARY_PATH. It needs you install the compiler in the C:\F directory : that is, you will have C:\F\G77\bin, etc.
Slight modification to the instructions on that page :
You should set PATH to C:\F\G77\bin
And LIBRARY_PATH to C:\F\G77\lib;C:\F\SLATEC\lib
This modification to LIBRARY_PATH allows you to compile with SLATEC simply with "-lslatec" as above.
A note about the compiler. It's G77, also know as GNU Fortran 77. An old compiler, integrated with the well known GCC suite until GCC 3.4.6 (we are at GCC 4.7.2 now). And the compiler you downloaded is for version GCC 2.95.
It's a good Fortran 77 compiler, but it's not very well optimized, and of course, you don't get any support for new processor features such as Intel SSE.
Modern Fortran compilers can still understand most if not all of Fortran 77, plus all the newer features of Fortran 90 and newer standards, which are extremely useful.
It may also be interesting to know there is another place to download the same compiler (eccept there is no SLATEC), just in case the page gets destroyed :
http://www.mbr-pwrc.usgs.gov/software/g77.html