Mixing C and assembly sources and build with cmake - c

I'm using eclipse for building a avr-gcc project that mixes assembly code and C source files.
I want to get rid of the automatic makefile generation of eclipse because I need to automate some process into the makefiles and for other reasons.
I used cmake some times ago and I was happy with it so I want to try to compile my source files using it. Everything run as expected with C sources. The problem is that at the end I need to compile some assembly files (actually 2) and add them to the target.
I googled around but I didn't found a way for doing this.
someone have an idea on how to do this?
The problem is that in eclipse I have
-x assembler-with-cpp
added to gcc argument list. I need to find a way for selectively add this param to the standard gcc argument list only for the asm files. I didn't find around any way for doing this.
thank you in advance
SOLUTION:
set in CMakeLists.txt every file to compile in the same list
enable_language(C ASM)
set ( SOURCES
foo.c
bar.c
foobar.s
)
add_executable(program ${SOURCES} )
in the Toolchain file you should place:
SET(ASM_OPTIONS "-x assembler-with-cpp")
SET(CMAKE_ASM_FLAGS "${CFLAGS} ${ASM_OPTIONS}" )
the second line is just if you need to pass extra options while compiling asm files. I wanted to pass all the CFLAGS plus some ASM_OPTIONS

CMake supports assembler out of the box. Just be sure to enable the "ASM" language in your project. If an assembler source file needs preprocessing, also set the source file's compilation options:
project(assembler C ASM)
set_property(SOURCE foo.s APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
add_executable(hello foo.s bar.c)

Based on your solution, one of the simplest solutions is this one-liner:
SET(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")

Related

Compiling files with own header in C

I am currently at the beginning stage of learning how to program in C, and I came across some questions regrading header files. For example
I have a header file named header.h,
which has int comp (int, int) declared in header.h and
defined in header.c
In such case, If i were to compile a test.c using the comp function, I would have to go like
gcc test.c header.c
First question: having to add header.c everytime I gcc seems too inconvenient and redundant. Is it a necessity? If not, is there a way I can get around it? If so, why? Or is it, in fact, not redundant compared to its usage, and am I just complaining?
Second question: if I were to use multiple .c files with functions declared in header.h my gcc would have to go
gcc test.c header.c header2.c header3.c .....
and that again seems too redundant. (and from hereon, same questions as First question..)
Thanks in advance. First time asking questions in SO. Please tell me if there is anyway I can improve the clarity of the question.
I think you are looking for the make, that automates the execution of the files you are compiling.
With the use of make, you don't need to write every time the commands like 'gcc test.c header1.c header2.c ...' in the terminal (if you type the commands directly to the terminal, yes, you will need to do this all the time, which is very redundant and costs lots of time). Using make, you only do this one time, and then all you have to do is run the make command.
You can see more about makefile at https://en.wikibooks.org/wiki/Make.
I hope it can help you.
You could make a shell macro or script to execute the command, if it is too much effort to use shell history feature to re-execute the command.
When your project starts to get complicated it's normal to use a build system in which you configure the build commands in the build system, and then you invoke the build system when you want to build. For example, write a Makefile that lists all the .c files using the right syntax for makefiles, and then type make each time you want to build.
You could consider using an Integrated Development Environment which is a (usually) GUI that includes a build system and other useful features, in which case you just need to hit a key to build and run.
It is often desirable to spread out your code across multiple files; this helps to ease code management. Header files provide a unified way to expose functions defined in libraries or source code files to other source code files without including the actual code for those functions. This way, the same header file can be included in multiple source code files without compiling the same code for each of those files. However, this means that the source code for functions in the header file must be given to the compiler also. As such, you have to give your header.c to the compiler each time you compile.
This does mean that you will compile header.c each time you build your project, which is a bit redundant. One way around this is to compile the header.c into an object file, and then give that the compiler when you build:
gcc -c header.c -o header.o
gcc header.o test.c
Furthermore, software developers often like to distribute their program functions to other developer but without providing the actaul code. To do this, they often use software libraries, which contain the compiled source code, along with header files to access this code. This is probably a little more than what your looking for, so I'll leave you read up on it.
All this is used not to reduce redundancy in your compiler commands, but in your compiled programs. To make programmers' lives easier building their programs, makefiles and IDEs are often used. These may be things you might have to read up on, but the other answers posted here should provide a good starting point.
Writing a simple Makefile is very useful for compiling C programs. Here's an example
CC = gcc
CFLAGS = -g -Wall
OBJECTS = main.o cfile1.o cfile2.o cfile3.o
run: $(OBJECTS)
$(CC) $(CFLAGS) -o run $(OBJECTS)
Don't worry about header files when writing a Makefile; only worry about your ".c" files. This example Makefile assumes that you want to compile main.c, cfile1.c, cfile2.c, and cfile3.c. When adding the C files to your Makefile, make sure to use ".o" instead of ".c".
The Makefile should be in the same directory as your C files and must be named "Makefile" with a capital M. Simply type "make" to compile. Then run the program with "./run".

Compiling with .lst file

I am trying to install the MIRACL library for my crypto system. While I was configuring the library, it gave me "miracle.lst" that contains list of files I need to compile. I was just wondering is there any way me to compile all files inside of .lst file once? I don't think it is an assembly file because it only contains names. I saw this link but it is nothing related with my situation.
List File In C (.LST)
Inside of miracl.lst
mrcore.c
mrarth0.c
mrarth1.c
mrarth2.c
...
In my case
gcc -I./include -c -O2 source/mr*.c

What is a multiple compilation, how is working and why i should use it?

I am learning C and I just read the term multiple compilation.Till now I had a single file.c and I used the command gcc file.c to compile it and then ./a.out to execute it. But I got confused a little bit. When should I use the multiple compilation instead of the single and which would be the possible reasons that they will lead me to prefer a multiple compilation instead of the single? I searched it and I found some articles but they didn't cover fully my questions. 1 (this is for c++) , 2If i undestood well if I have some files.c in my project eg file1.c, file2.c and then i want to link them, i execute
gcc file1.c
gcc file.c
gcc file1.o file2.o //somehow i have to create the .o files..
Thank you..
Compilation takes time. There's no point in re-compiling C code that hasn't changed. So, for large projects, it makes sense to split the code into multiple files (typically not randomly of course, but into modules of different functionality) and compile them only when needed.
Linking is the process of taking a bunch of object code (what the .o files are called) and turning them into a single program.
There are many steps to compiling.
When you invoke gcc it will create by default an executable file i.e. all steps in one go:
.c -> .i preprocessor
.i -> .s compiler
.s -> .o assembler
*.o -> a.out linker
Generally the first two take up the most time. If you have a large project then recompiling the entire project may take a lot of time when you are developing. So the compiler allows you to stop at a certain point and reuse previous results of files that have not changed:
gcc -E for preprocess only (rarely used)
gcc -S compile, but don't assemble. Useful for debugging or optimising assembly
gcc -c compile, assemble, but don't link. This is the most commonly used one and produces object files. Those contain your assembled functions (object code), but it's not capable of running because not all functions may be present yet, library functions are missing and the executable header has not been linked in.
The final step gcc -o executable *.o will then take all those and link them together to create an executable. Optionally linking libraries into it.
Generally having all functions in one source file will allow the compiler to do the more optimisations (i.e. inlining), but at the cost of compile time.
Have a look at https://cs.senecac.on.ca/~btp200/pages/images/compile_link.png

AIX xlC cross-compilation/linkage for C++ not finding C symbols

I am attempting to cross-compile on AIX with the xlc/xlC compilers.
The code compiles successfully when it uses the default settings on another machine. The code actually successfully compiles with the cross-compilation, but the problem comes from the linker. This is the command which links the objects together:
$(CHILD_OS)/usr/vacpp/bin/xlC -q32 -qnolib -brtl -o $(EXECUTABLE) $(OBJECT_FILES)
-L$(CHILD_OS)/usr/lib
-L$(CHILD_OS)/usr/vacpp/lib/profiled
-L$(CHILD_OS)/usr/vacpp/lib
-L$(CHILD_OS)/usr/vac/lib
-L$(CHILD_OS)/usr/lib
-lc -lC -lnsl -lpthread
-F$(CHILD_OS)$(CUSTOM_CONFIG_FILE_LOCATION)
When I attempt to link the code, I get several Undefined symbols:
.setsockopt(int,int,int,const void*,unsigned long), .socket(int,int,int), .connect(int,const sockaddr*,unsigned long), etc.
I have discovered that the symbols missing are from the standard c library, libc.a. When I looked up the symbols with nm for the libc.a that is being picked up, the symbols do indeed exist. I am guessing that there might be a problem with the C++ being unable to read the C objects, but I am truly shooting in the dark.
Sound like it might be a C++ name mangling problem.
Run nm on the object files to find out the symbols that they are looking for. Then compare the exact names against the libraries.
Then check the compilation commands, to ensure that the right version of the header files is being included - maybe it's including the parent OS's copy by mistake?
I was eventually able to get around this. It looks like I was using the C++ compiler for .c files. Using the xlc compiler instead of the xlC compiler for C files fixed this problem.

Compiling Small Gcc Project on Windows Using MinGW

so I've been programming in C++ for almost 2 years now, and the whole while I've had the pleasure of using an IDE (VS) with lovely project settings and automatic linking and the like. I've always stayed away from any external libraries which required me to compile via makefiles, or at least the ones which were meant for linux environments/other compilers.
Anyways I now want to use a super handy utility (Bob Jenkins Perfect Minimal Hash) but it requires me to compile via makefiles, not only that but using the g++ compiler.
I went ahead and got the mingW32-make utility and am now trying to get it to work. Where I'm at now:
Succesfully installed minGW
Succesfully called the make utility
Failed to succesfully make the project.
The error I get is:
C:\gen_progs\ph>mingw32-make
mingw32-make: *** No rule to make
target lookupa.c', needed by lookupa.o'. Stop.
And the makefile itself:
CFLAGS = -O
.cc.o:
gcc $(CFLAGS) -c $<
O = lookupa.o recycle.o perfhex.o perfect.o
const64 : $(O)
gcc -o perfect $(O) -lm
# DEPENDENCIES
lookupa.o : lookupa.c standard.h lookupa.h
recycle.o : recycle.c standard.h recycle.h
perfhex.o : perfhex.c standard.h lookupa.h recycle.h perfect.h
perfect.o : perfect.c standard.h lookupa.h recycle.h perfect.h
Now the error seems reasonable, at least from my minimal understanding of makefiles, I have all the referenced .c, .h files, however I have none of the .o files and there doesn't appear to be any instructions on how to make these. So my question/s are:
am I calling the make utility wrong? Or do I need to compile the object files first? Or... do I need to add something to the make file?
Again I have all the referenced .c and .h files.
Edit: Sorry about that I was actually missing that specific file it seems to have disapeared somewhere along the line. However, adding it back in this is the error I now get:
c:\gen_progs\ph>mingw32-make
cc -O -c -o lookupa.o lookupa.c
process_begin: CreateProcess(NULL, cc -O -c -o lookupa.o lookupa.c, ...) failed.
make (e=2): The system cannot find the file specified.
mingw32-make: *** [lookupa.o] Error 2
Regarding your error "process_begin: CreateProcess(NULL, cc -O -c -o lookupa.o lookupa.c, ...) failed."
This is because the make utility wants to use the "cc" compiler to compile your program, but that compiler is not part of the Mingw-package.
Solution: Change the ".cc.o:" to ".c.o:". This changes the implicit rule which tells Make what compiler to use (gcc on the next line) when compiling .c files (the original line tells it how to compile .cc files).
Saying either make -DCC=gcc at the command line or adding the line CC=gcc to the top of the Makefile would cure the issue as well. Make's built in rules for handling C source code all name the C compiler with the variable CC, which defaults to "cc" for reasons of backward compatibility even in Gnu Make.
It looks like the original Makefile author tried to work around that problem by supplying a custom rule for compiling .cc files, but since there are no .cc files in the project that rule was not actually used.
Specifying the correct value for CC is superior to fixing the explicit rule to name .c files IMHO because Makefiles are generally easier to use and maintain and are the most portable when the least possible information is specified.
I don't think not having .o files is the problem. Make will make them from the source files (the files to the right of the colon).
Your immediate problem seems to be that make can't file the file "lookupa.c". From the rules you posted, it looks to me like that file should be sitting in the same directory as the makefile, but it isn't. You need to figure out where that file is, and how to get it there.
(For some reason I have a mental image of Wile E. Coyote sitting at his computer, seeing that file name, looking up, and getting plastered with an anvil).

Resources