Linking a .s file with CMake - gcc

I have a c function that I'd like to use but thats compiled with the Intel compiler instead of the gnu C compiler. I'm using cmake to build the program.
(I'm actually using ROS and hence rosmake but the base is cmake so I think its more of a cmake issue than a ROS issue).
Suppose the file built with icc is x.c and produces an x.s file. I want to use the function a() from x.c in my file y.cpp.
In y.cpp I have:
#include "x.h"
.....
call a()
which works if CMakeLists.txt has
rosbuild_add_executable(y y.cpp x.c)
rosbuild_add_executable is analogous to add_executable(...)
but if I build x.c with icc and try to include the x.s file instead:
rosbuild_add_executable(y y.cpp x.s)
It doesnt work. Is there some change I should make to the way I call a() in y.cpp? or is there some other way to link it.

When using gcc, you can compile .S files with your C compiler (no explicit invocation of asm needed). CMake can be told to do so using
set_property(SOURCE <myfile>.S PROPERTY LANGUAGE C)
for each of your .S files.

To work with .s files you'll have to enable assembly language support in CMake with enable_language.
You can find more information here: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/languages/Assembler

Related

Is it possible for gcc to name mangle?

I had some code that wasn't working until I added extern "C" before the name of a function, even though I was compiling using gcc. The file's name did, however, end in ".cpp".
Is it possible for gcc to name mangle? Did it intelligently pick up the file extension ".cpp"?
The gcc compiler driver looks at the file extension. If it is .cpp (or .cc, .C and a few more), the file is compiled as a C++ file:
Compiling C++ Programs

Assembly can be linked when compiling with GCC but not with G++, why and how to fix?

I always thought C++ was C with some libraries built on top. And I thought any C program could be compiled with g++, I seem to be wrong.
I have some assembly code that can be sumarized as
_start:
b kernel_main
I then have some c code in main.
If I compile and link with gcc, everything works. If I try to compile the same code with G++ (absolutely no change, not even file extensions)
I get the error:
In function `_start':
(.init+0x4): undefined reference to `kernel_main'
So G++ couldn't find the kernel_main label. Upon further inspection (disassembling binaries) it seems that g++ changes the kernel_main label to be _Z11kernel_mainv. Is there any way to tell g++ to keep labels intact?
g++ will treat inputs files (even with .c extension) as C++ and consequently mangle names of functions unless they have been marked with extern "C". So kernel_main has turned into something like _Z11kernel_mainv.

Assembler used by golang when building with and without cgo

Let's say I have a golang package, which contains some assembly code:
demopkg/
source1.go
source2.go
asm_amd64.s
If I try to build it using go build, toolchain will use go tool asm to assemble the *.s files.
But if I add Cgo to the mixture, by putting a single import "C" into any of the sources, go will switch to gcc assembler.
I can see it by executing go build -n. Calls to the /usr/local/go/pkg/tool/linux_amd64/asm from the first case get replaced by calls to gcc. Besides that, it starts complaining about broken syntax.
Is this behaviour documented, so I can rely on it for the maintaining of my package? Can I force go build to use one exact assembler?
Yes, it's in the cgo documentation
When the Go tool sees that one or more Go files use the special import
"C", it will look for other non-Go files in the directory and compile
them as part of the Go package. Any .c, .s, or .S files will be
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
compiled with the C++ compiler. Any .h, .hh, .hpp, or .hxx files will
not be compiled separately, but, if these header files are changed,
the C and C++ files will be recompiled. The default C and C++
compilers may be changed by the CC and CXX environment variables,
respectively; those environment variables may include command line
options.

How to include in CMake the files on which Eigen depends?

I am working on a C project which I downloaded from the Internet.
I am trying to add some functions in which Eigen is to be used for linear algebra.
To that end, I added the following lines to the CMakeLists.txt :
PKG_CHECK_MODULES(EIGEN3 REQUIRED eigen3)
INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
LINK_DIRECTORIES(${EIGEN3_LIBRARY_DIRS})
ADD_EXECUTABLE(main main.c)
TARGET_LINK_LIBRARIES(main ${EIGEN3_LIBRARIES})
and I get no errors when running cmake . and then make
The issue is when I try to include <Eigen/Dense> in one of the c functions, I get the following error when I try to make:
/usr/include/eigen3/Eigen/Core:28:19: fatal error: complex: No such file or directory #include <complex>
Eigen/Dense includes Eigen/Core and Eigen/Core includes <complex>
I think it's just not looking in the correct directory to find complex... How to make it look there?
Eigen in C++ library, while your application source is C file (main.c). Since it has a .c extension, CMake threats it as C source and use C compiler, which doesn't know about C++ standard library (<complex>). Rename main.c to main.cpp.

Compile preprocessor output using gcc

I've generated a preprocessor out using the -Ecommand.
Is it possible to compile exactly that generated file using gcc?
Yes, just save the output as a C or C++ file (or whatever the input was).
That's exactly what GCC does, schematically speaking: preprocess, then compile.

Resources