Missing header files for linked ".c" file - linker

I have linked a ".c" file to another one. ld doesn't return any error but the compiler can't find included header files in this ".c" file and returns this error:
../libvmi/driver/xen.c:27:20: fatal error: libvmi.h: No such file or directory
Here is the Makefile of my project:
## Source directory
SUBDIRS =
INCLUDES = -I$(top_srcdir) $(top_srcdir)/libvmi
AM_LDFLAGS = -L$(top_srcdir)/libvmi/.libs/ $(top_srcdir)/libvmi/driver $(top_srcdir)/libvmi/libvmi.h
LDADD = -lvmi -lm $(LIBS) $(top_srcdir)/libvmi/driver/xen.c $(top_srcdir)/libvmi/libvmi.h
bin_PROGRAMS = module-list process-list map-symbol map-addr dump-memory
module_list_SOURCES = module-list.c
process_list_SOURCES = process-list.c
map_symbol_SOURCES = map-symbol.c
map_addr_SOURCES = map-addr.c
dump_memory_SOURCES = dump-memory.c
As you see above I thought I should add "$(top_srcdir)/libvmi" to "INCLUDES"; this is the directory that libvmi.h is located.
The original Makefile is:
## Source directory
SUBDIRS =
INCLUDES = -I$(top_srcdir)
AM_LDFLAGS = -L$(top_srcdir)/libvmi/.libs/
LDADD = -lvmi -lm $(LIBS)
c_sources = process-list.c $(top_srcdir)/libvmi/driver/xen.c
bin_PROGRAMS = module-list process-list map-symbol map-addr dump-memory
module_list_SOURCES = module-list.c
process_list_SOURCES = $(c_sources)
map_symbol_SOURCES = map-symbol.c
map_addr_SOURCES = map-addr.c
dump_memory_SOURCES = dump-memory.c
I have modified it to link "libvmi/driver/xen.c" to process-list.c file which are located in different directories.
This is because of something's wrong in Makefile, yes?

Add a -I to the path you added. Note this is a compiler, not linker question

The reason ld doesn't return an error is because it is not invoked. The error message you are getting is coming from the compiler, and the loader is not invoked until the compiler is successful.
Yes, you do need to add $(source_dir)/libvmi to INCLUDES; you just need to do it symmetrically with the existing entry:
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libvmi
Note the -I preceding the directory name. You have a similar problem in AM_LDFLAGS and LDADD:
AM_LDFLAGS = -L$(top_srcdir)/libvmi/.libs/ -L$(top_srcdir)/libvmi/driver
LDADD = -lvmi -lm $(LIBS)
but you do not want to add the header file $(top_srcdir)/libvmi/libvmi.h to the load flags. Headers are not libraries; headers are not appropriate for sending to the linker/loader. You should only supply the linker/loader with object files, libraries, and options — no source files, no headers.
That more or less deals with the surface issues. What is the real problem you are trying to solve?
If you need to link with code from a library built in libvmi directory, why don't you make the dependency changes in this makefile to pick up the library from the libvmi directory (and separately run the build for the library in the libvmi directory)? Or, if you really want to do the compilation in the current directory (but why?), create links to the libvmi files locally (or copy them; no, on second thoughts, don't copy them), and compile them locally? Mixed directory working is painful at best — and to be avoided when possible, which it almost always is.
I note that the original makefile does in fact include -lvmi on the link line, so what I outlined is what you're expected to use. Why isn't that working for you? This is very much an XY Problem. I recommend reworking the question so that you get a solution to the real problem you started out with, rather than the artificial problem you ran into attempting to solve the real problem in a misguided way.

Related

How to include external library to omnetpp Makefile

I am new to omnetpp. In my source file, I include zmq.h header and I can successfully make Makefile with opp_makemake --make-so -f --deep
Next, running make does not give any errors either
Creating shared library: out/gcc-release//libtictoc_r.so
So I am expecting, that zmq library has already been linked.
However, when I run
opp_run -l tictoc_r
I get
<!> Error: Cannot load library 'libtictoc_r.so': ./libtictoc_r.so: undefined symbol: zmq_strerror
Thus I doubt if zmq library had been linked correctly.
By the way, the header files for zmq are located in the standard directory, i.e.
find /usr/include/ -name "*zmq*"
returns
/usr/include/zmq.h
/usr/include/zmq_utils.h
/usr/include/zmq_addon.hpp
/usr/include/zmq.hpp
How could I solve my problem?
Using the header files does not say anything about where the actual shared object file is present. You must add -lzmq (or whatever the library is called) to your linker flags in the project.
The easiest way is to create a makefrag file in the source folder (where the Makefile is generated) and add
LDFLAGS += -lzmq
to it. The generated Makefile will include the makefrag file and that one can add to the linker flags. (the samples/sockets example does this too)
You can also add the required extra linker flags in the IDE's project properties dialog.

Contiki: undefined reference to a function defined in a separate source file

I am writing a program using the Contiki operating system.
I have the remote_firmware.c file and a folder called parser with the files parser.h and parser.c where I wrote the method void test(). I included parser.h in remote_firmware.c with:
#include "parser/parser.h"
The Makefile looks like this:
CONTIKI_PROJECT = remote_firmware
all: $(CONTIKI_PROJECT)
#UIP_CONF_IPV6=1
CONTIKI_WITH_RIME = 1
CONTIKI = $(HOME)/contiki
include $(CONTIKI)/Makefile.include
When I try to build this the Error occurs:
undefined reference to 'test'
I am aware that the Makefile needs to know about parser.h, but I do not know how. I tried several solutions which were proposed here but I guess I did something wrong. Maybe somebody of you know what to do?
Thank you a lot.
Where is your source file located? Try adding the source file name to the PROJECT_SOURCEFILES preprocessor variable (i.e PROJECT_SOURCEFILES+=parser.c) and adding the location of the source file to the CONTIKIDIRS preprocessor variable (i.e CONTIKIDIRS+={Directory}).
If parser.c depends on a lot other C files you might want create an C library archive first and then adding the library to your project by adding the name of the library to the TARGET_LIBFILES variable.
The error undefined reference to test is an error from the linker not the compiler. It has nothing to do with including a header file. It means when you linked the executable you didn't include parser.o

Where is the start point of this makefile

The following is a makefile I encountered in Postgres, I don't understand how it works. I saw some simple Makefile examples where they have commands to compile, but this one seems to be different. Could anyone explain how this makefile works? Basically I need to understand this one before I modify it for my purpose.
subdir = src/backend/access/transam
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = clog.o multixact.o \
xlogreader.o xlogutils.o
include $(top_srcdir)/src/backend/common.mk
xlog.o: xlog.c $(top_srcdir)/src/include/catalog/catversion.h
Please let me know if you need more information.
Thanks.
subdir = src/backend/access/transam
top_builddir = ../../../..
Set some variables
include $(top_builddir)/src/Makefile.global
Include a global makefile (presumably uses the two previously set variables in some way).
OBJS = clog.o multixact.o \
xlogreader.o xlogutils.o
Create an OBJS variable for the things to be built in this directory (I assume).
include $(top_srcdir)/src/backend/common.mk
Include another makefile (which presumably uses OBJS and defines rules/flags/etc. for building files).
xlog.o: xlog.c $(top_srcdir)/src/include/catalog/catversion.h
Explicitly handle prerequisites to the xlog.o target file (presumably because putting this in OBJS would do something undesirable).
For more about what subdir or OBJS is used for exactly (or what else you can set in this file) you would need to read and understand src/Makefile.global and src/backend/common.mk.

How to use autotools for deep projects?

I have a C project that has the following structure
Main/
Makefile.am
bin/
src/
Makefile.am
main.c
SomeLibrarySource/
SomeFuncs.c
SomeFuncs.h
The main.c contains the main function that uses functions defined in the SomeFuncs.{h/c} files.
I want to use autotools for this project. I read a couple of resources on autotools. But, I was only able to manage using autotools for a single level project where all source, object and other files reside in the same directory.
Then I got some links that talked about using autotools for deep projects like this one and then I got confused.
Right now I have two Makefile.am as follows
Makefile.am
SUBDIRS=src
src/Makefile.am
mainprgdir=../
mainprg_PROGRAMS=main
main_SOURCES=main.c
I am pretty sure that these files should not be as I have them now :P
How do I use autotools for the above project structure? (At least what should be there in those Makefile.am(s) and where should I place them.
EDIT:
One more thing! At the end I would like to have the object files created in the bin directory.
Thanks
mainprogdir=../ does not make a whole lot of sense (you don't know what it is relative to on installation). Probably intended:
# Main/Makefile.am
# .━━ target for `make install`
# |
# ↓ ↓━━ target for compilation
bin_PROGRAMS = bin/main
# ↓━━ based upon compilation target name
bin_main_SOURCES = src/main.c
There are two main approaches. If the functions in SomeLibrarySource are used only by main, then there's no need to build a separate library and you can simply specify the source files in src/Makefile.am
main_SOURCES = main.c SomeLibrarySource/SomeFuncs.c
However, if you actually want to use the functions in other code in your tree, you do not want to compile SomeFuncs.c multiple times but should use a convenience library.
# Assigning main_SOURCES is redundant
main_SOURCES = main.c
main_LDADD = SomeLibrarySource/libSomeFuncs.a
noinst_LIBRARIES = SomeLibrarySource/libSomeFuncs.a
AM_CPPFLAGS = -I$(srcdir)/SomeLibrarySource
(You'll need AC_PROG_RANLIB in configure.ac to use convenience libraries.)
If the source file is named SomeFuncs.c, automake will not need Makefile.am to specify SomeLibrarySource_libSomeFuncs_a_SOURCES, but if the name of the source code file does not match the name specified in noinst_LIBRARIES, SomeLibrarySource_libSomeFuncs_a_SOURCES should be set to the list of files used to build the library. Note that you do not need to specify main_SOURCES, since main.c is the default value if left unspecified (but it's not a bad idea to be explicit.) (In all of this, I am not comfortable use CamlCase names, but the system I'm using uses a case insensitive file system (biggest mistake apple ever made) and the examples I give here are working for me. YMMV)
You could of course do a recursive make, or build the library as a separate project and install it. (I like the final option. Libraries with useful features should exist on their own.)

SCons to make a shared library (.so) with a static library (.a)

I'm trying to get SCons to make a shared library. One of the items going into the .so is a .a static lib.
I have a line like:
env_2.SharedLibrary('libstuff.so', \
Split("""stuff.cxx mylib/libMine.a""")
And upon running it, I get this error:
scons: *** Source file: mylib/libMine.a \
is static and is not compatible with shared target: libstuff.so
However, I know that a shared library can be made from the .a via a command like:
g++ -m32 -shared -o libstuff.so stuff.o mylib/libMine.a
Any ideas on getting this to work or any workarounds would be greatly appreciated.
Related question: How do I get scons to put an additional string -shared on the LINK command line for the Program() call? If I could do this, I think it would meet my needs.
Try to set env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1 in your SConstruct.
This problem is not specific to scons. To build a shared library, you'll need objects that are compiled with position independent code (-fPIC). Your best bet is to make the shared library out of the source files compiled with the right options.
In SCons, you can define a list of targets that's used to build both libMine.a and libShared.so.
Update: for your second question, the SharedLibrary builder might do what you need:
SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])
If not, LINKFLAGS sets the flags passed to a link command.
I've the same problem under cygwin. I passed '-fPIC' options to gcc when building the objects and got the following warning:
warning: -fPIC ignored for target (all code is position independent)
I also passed '-shared' to the link command. And I finally got the error
"***.lib is static and is not compatible with shared target: myso.dll"
It seems scons doesn't allow to create so directly from obj or lib files, and one can either create the so from a list of sources files (using SharedLibrary()) or source file + 'LIBS' option like dummytaurus says. I'm curious about that.
env_2.SharedLibrary('libstuff.so', Split("""stuff.cxx"""), LIBS='libMine.a', LIBPATH='mylib')
This should work.
The problem is in the function SharedFlagChecker (Default.py), which checks only for an internal "shared" flag. The SCons documentation leads you to believe that it keeps the distinction between shared objects and static objects via the suffix (SHOBJSUFFIX), but not so. The fix is easy. In the file scons-local.../SCons/Default.py find the SharedFlagCheckerand edit:
def SharedFlagChecker(source, target, env):
same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
if same == '0' or same == '' or same == 'False':
for src in source:
try:
shared = src.attributes.shared
except AttributeError:
# Replace this line: shared = None
shared = env.Dictionary()['SHOBJSUFFIX'] == src.suffix
if not shared:
raise SCons.Errors.UserError("Source file: ...")
Now objects made via the SharedObject builder will be linkable in a shared library.
The solution to resolve this issue have been used a 'SharedObject' as the following:
ASN1CObjectFile = envCProcesses.SharedObject(target = "OTCMsg.os",
source = "OTCMsg.c",
CFLAGS = envCProcesses["CFLAGS"] + ["-Wno-unused"])
and:
OTCLibSharedLibrary = envCProcesses.SharedLibrary(env["OTC_LIBPATH"] + "/libOTCLib" + env["SHLIBSUFFIX"],
ASN1CObjectFile +
[ASN1AllocatorSource,
"OTCLib.c"],
LIBPREFIX = "")
Best regards,

Resources