I have a python file that I want to run on the board. Hence I want to embed the python interpreter (written in C) in the board. I managed to write separate C project that runs the Python file. It compiles and runs as I want to. Here's the makefile for same:-
CC=gcc
CFLAGS=-I python3.5 -I config -I . -c -w
LDFLAGS= -lpython3.5m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
all: classifier trainer test link
test:
$(CC) $(CFLAGS) test.c
trainer: Trainer.c
$(CC) $(CFLAGS) Trainer.c
$(CC) Trainer.o $(LDFLAGS) -o Trainer
.ONESHELL:
classifier: Classifier.c
$(CC) $(CFLAGS) Classifier.c
# $(CC) Classifier.o $(LLFLAGS) -o Classifier
link:
$(CC) test.o Classifier.o $(LDFLAGS) -o test
clean:
rm -f Trainer.o Trainer Classifier.o Classifier
http://dpaste.com/3BCY2RE is my entire directory of project "hello" (It is not the one from the examples).
I included "Classifier.h" in my "hello.c" and I am getting the following errors: http://dpaste.com/3KKCF84
Compiler include options (No preincludes):
"${CG_TOOL_ROOT}/include"
"${workspace_loc:/${ProjName}/TerrainPredict}"
"${workspace_loc:/${ProjName}/TerrainPredict/config}"
"${workspace_loc:/${ProjName}/TerrainPredict/python3.5}"
"${SW_ROOT}/examples/boards/ek-tm4c1294xl"
"${SW_ROOT}"
Linker file search paths:
"libc.a"
"${workspace_loc:/${ProjName}/TerrainPredict/libterrainclf.a}"
"${SW_ROOT}/driverlib/ccs/Debug/driverlib.lib"
and:
"${CG_TOOL_ROOT}/lib"
"${workspace_loc:/hello/TerrainPredict/libterrainclf.a}"
"${CG_TOOL_ROOT}/include"
Am I wrong with some of my configurations? Or is this some problem with python interpreter? Any help is greatly appreciated
EDIT:-
As #KevinDTimm suggested, the problem is that there is no pyconfig.h for my environment. This file is required by python to define important variables like source of system clock. I tried removing safety checks in existing pyconfig.h. The first error I am getting is in pytime.h as :
"_PyTime_t need signed 64-bit integer type"
Which was further because of the following code block:
#ifdef PY_INT64_T
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
store a duration, and so indirectly a date (related to another date, like
UNIX epoch). */
typedef PY_INT64_T _PyTime_t;
#define _PyTime_MIN PY_LLONG_MIN
#define _PyTime_MAX PY_LLONG_MAX
#else
# error "_PyTime_t need signed 64-bit integer type"
#endif
It appears to me that it needs a variable that stores time. I need help in assigning that variable.
From the linked problem
The multiarch error message is a bit misleading. It's not failing because there's a multiarch problem, it's failing because there's a multi-OS problem. /usr/include/python*/pyconfig.h is trying to figure out where to find the real pyconfig.h from, and since it doesn't know, it's bailing out.
You essentially need a pyconfig.h generated for the target environment. I don't know what produced pyconfig.h, perhaps building cython from source? pyconfig.h looks like something generated by gnu autoconf, so there should not be any big problems in generating it.
Related
Hello I'm having a hard time understanding makefiles. I play with them to understand them better but here's the issue:
all: main
main: main.o funcIO.o funcMan.o
$(CC) -o $# $^
----------------------------------
funcIO.o: funcIO.c
$(CC) -c -o funcIO.o funcIO.c
funcMan.o: funcMan.o
$(CC) -c -o funcMan.o funcMan.c
This works regardless if everything below the punctured line is there or not. I'm told that this is the right way to write makefiles but why does it work without the targets funcIO.o and funcMan.o and if it works without them, why do we write them? Can you explain it like I'm 5 years old?
Thanks for your time!
Assuming you're using GNU Make (it might be the same for other Makes), this works due to built-in rules. Make already knows how to compile a C source file, and unless you tell it otherwise, it applies this recipe to it:
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
$# is the target of the rule (the filename of the .o file) and $< is the first prerequisite (the filename of the .c file). The other variables have sensible defaults (mostly empty).
The right way to use Makefiles is to keep them as small as possible. Makefiles are about determining dependencies and only incidentally can be used to build programs. Here's how I would rewrite your Makefile:
all: main
main: main.o funcIO.o funcMan.o
And I only put the all target there because you had it to begin with. Make has a list of builtin rules that know how to build things given certain files as inputs. If you ask it for a .o file, it will look for a file of the same name, but with the extension of .c, .cpp, .f77, etc., and run the rule that builds what you asked for using that prerequisite file. You don't even need to specify how to build those, they come for free! It's the more complex relationships (such as a final binary) that need to be spelled out, as shown in my above example. There's a similar rule for building a binary out of .o files (assuming one of them has the same name as the binary, which yours does), so you don't need to specify any tasks, just the dependencies. You can control how they are run by adjusting special flags:
CFLAGS += -Wall -Wextra -Wpedantic
main: main.o funcIO.c funcMan.o
main: LDLIBS += -lm
This version builds every C-compiled file with those CFLAGS, and builds main while linking in the -lm math library.
If you are building normal C programs, I strongly recommend this approach. Specify the prerequisites of the final binary, and control builds through these Make variables.
I was looking at the net-snmp code and I found something odd in the Makefile of the snmplib itself. The last couple of thousands of lines are nothing but rules in this form:
./dir_utils.lo: ../include/net-snmp/output_api.h
for EVERY library object and header file. Even those that are not compiled, depending on which flags are selected in the configure script.
I looked at the "make" manual but I didn't find this exact case. It may be (as stated in 5.9) that they do this to exclude the possibility that an implicit recipe is called on the target, but other than that I have no idea.
Another reason might be to "break" the compilation if the library is tampered with (deleting whatever header in the project causes in fact the makefile to crash because it can't execute the rule).
This is an educated guess but I would like to know the theory behind this. I mean the makefile already builds whatever it has to build, why include all these rules in explicit form?
Thanks
As I expect you know, the Makefile is generated by the ./configure script.
All the lines that interest you are auto-generated dependencies. Actually,
they are just the appended contents of the file Makefile.depend in the same
directory, which is part of the distribution and was generated with the aid
of gcc ahead of time.
So e.g.
./dir_utils.lo: ../include/net-snmp/output_api.h
just informs make of the vitally important fact that ./dir_utils.lo
depends on ../include/net-snmp/output_api.h. Then if ./dir_utils.lo
is older than ../include/net-snmp/output_api.h, make will re-make
./dir_utils.lo provided it has some recipe to do that, which it has.
Here is a project:
main.c
#include "hw.h"
#include <stdio.h>
int main(void)
{
puts(HW);
return 0;
}
hw.h
#ifndef HW_H
#define HW_H
#define HW "Hello World"
#endif
Makefile
CC := gcc
.PHONY: all clean
all: hw
hw: main.o
$(CC) -o $# $<
clean:
rm -f hw main.o
Build and run it:
$ make && ./hw
gcc -c -o main.o main.c
gcc -o hw main.o
Hello World
But there's a bug in the makefile. It doesn't know that main.o
depends on hw.h:
$ touch hw.h
$ make
make: Nothing to be done for 'all'.
Append that dependency to the makefile:
main.o: hw.h
and retry:
$ make
gcc -c -o main.o main.c
gcc -o hw main.o
Bug fixed.
I encountered this problem while installing some python modules in which had dependencies on their own C libraries. The problem is, cc is not looking into /usr/local/include at all for header files. I made it work for one of those (thinking it was a problem of the modules) by adding /usr/local/include as one of the external include directories.
Then, to test, I wrote a simple hello.c file and added #include "fftw3.h" / #include <fftw3.h> and it failed to compile if I didn't explicitly add -I/usr/local/include.
I added a line in my ~/.bash_profile to export the include the directory path to $PATH; didn't work either.
So, my question is, how do I make cc look for header files in /usr/local/include (or, for that matter, in any custom directory) always without passing -I flag?
FYI: I'm using macbook pro running OSX 10.11
If you are using GCC then you have three environment variables you can use:
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
Take a look here.
EDIT: since you specified you are working with OS X (hence Clang), they should be supported too, take a look ad the end here. It's not uncommon to have Clang mimic GCC specs just to help in compatibility.
I think you should invest some time in understanding build systems. For example gnu make. Here, look at this:
CC = gcc
CFLAGS = -Wall
DEPS = primes.h
OBJ = go.o primes.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
go: $(OBJ)
gcc $(CFLAGS) -o $# $^
This gives you:
The freedom to add any compiler you want. In your case that would be cc, in this example it is gcc.
use cflags to control to adjust the compiler - in the example -Wall will turn on the warnings
make your build work reproducible
prepare recipe with complex rules for compilation as your application grow
More information is available here.
This is my absolute first time ever making a makefile, and I'm really trying to understand the process.
I'm trying to create a very simple makefile for a C++ project whose structure is as follows:
root folder
makefile
readme
src folder
...source files all here...
include folder
...header files for external libraries here...
lib folder
...external lib files all here...
bin folder
...output directory for built executable...
obj folder
...object files all here...
I followed the tutorial here.
Here's my makefile:
IDIR=include .
CC=g++
CFLAGS=-I$(IDIR)
ODIR=bin/obj
LDIR=lib
LIBS=none
SRC=src
_DEPS=hello.h
DEPS=$(patsubst %,$(IDIR)/,%(_DEPS))
_OBJ=file1.o file2.o
OBJ=$(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(SRC)/%.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS) # $(LIBS)
test_proj: $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
When I run make on this, I get the following error:
g++ -o .o
g++: fatal error: no input files
compilation terminated.
<builtin>: recipe for target '.o' failed
mingw32-make.exe: *** [.o] Error 1
I'm using GNU Make 3.82.90 built for i686-pc-mingw32, if that matters at all.
Can anyone point out whatever ridiculous error I'm making?
IDIR=include .
is the first problem. Replace it by:
IDIR=include
With your code CFLAGS is expanded as:
-Iinclude .
It does not make sense, I'm afraid. The second problem is:
DEPS=$(patsubst %,$(IDIR)/,%(_DEPS))
which should probably be:
DEPS=$(patsubst %,$(IDIR)/%,$(_DEPS))
and would expand as:
DEPS=include/hello.h
if you fix the first problem, else as:
DEPS=include ./hello.h
which does not make sense neither. The cumulated effect of these two errors are strange recipes (I didn't try to expand them by hand) that probably trigger a make implicit rule with wrong parameters.
IDIR=include .
CC=g++
CFLAGS=-I$(IDIR)
This is wrong. First, for C++ code, use CXX not CC and CXXFLAGS not CFLAGS. Run make -p to understand the builtin rules of your make.
Then -I$(IDIR) does not "distribute" the -I, and IDIR is never used elsewhere. So I suggest to start your Makefile with:
CXX=g++
MY_CXX_LANG_FLAGS= -std=c++11
MY_CXX_WARN_FLAGS= -Wall -Wextra
MY_CXX_INCL_FLAGS= -I. -Iinclude
MY_CXX_MACRO_FLAGS= -DMYFOO=32
### replace with -O2 for a release build below
MY_CXX_OPTIM_FLAGS= -g
CXXFLAGS= $(MY_CXX_LANG_FLAGS) $(MY_CXX_WARN_FLAGS) \
$(MY_CXX_INCL_FLAGS) $(MY_CXX_MACRO_FLAGS)
I won't improve your Makefile, but I do suggest to upgrade to GNU make version 4 if possible (and compiling make 4.1 from its source code is worthwhile in 2015) for that purpose. If possible enable GUILE scripting in it.
If you are forced to use make 3.82 debug your Makefile using remake (with -x); if you can afford a make version 4 use its --trace option
BTW, you might consider using automatic dependencies, that is generating dependencies by passing -M or -MG (etc) flags of g++, see that.
At last, a simple project for a small program (less than a hundred thousands of source lines) might just put all (a few dozens of) its files in the current directory (then the Makefile could be simpler); your proposed directory structure might be arcane for a simple project (but could worth the pain if you have millions of C++ source lines of code). I've given several simple examples of Makefile, e.g. this & that. And GNU make source code itself has a less complex file tree that what you want.
BTW, I strongly disagree with the opinions of that answer (which I did upvote, since it is helpful). I don't feel that GNU make is senile, but I regret that, instead of using recent features available on recent versions (4.x) of make, many people prefer to use complex and arcane Makefile generators (like cmake) instead of coding a clever Makefile (for make version 4 specifically).
At last, you could use other builders, e.g. omake, icmake, ....
Long story short: We have a large SDK containing ~1Gb of hairy code hacked together by Elbonian Code Slaves, duck-taped together by a quivering lattice of RPC's, shared memory, mutex/semaphores, and spit. It's compiled on a Linux machine for an embedded SoC target.
As part of a stab at improving part of the code, I want to add POSIX Semaphores to one of the sources, which gets included by a few RPC routines.
However, just writing some valid code & sticking
#include <semaphore.h>
at the top is of course insufficient to enable compilation.
What is required are special flags in the makefile, depending on what you read it could be any/all of:
-pthread
-lpthread
-lpthreads
-lrt
-rt
I do not have a great deal of experience writing makefiles, and unfortunately due to the size of the codebase there are multiple nested levels of them (upwards of 2,000 makefiles in the SDK) with all sorts of dependencies, all spawning from the One True Makefile in the root folder.
There is a lot of macroification(TM) going on in the makefiles which is not helping my efforts to unravel the correct incantation.
As a glimpse of the structure of the project and the file I'm trying to modify, the folder structure is something like:
/home/project/kernel/... Contains the Linux kernel & PSP / BSP
/home/project/the_system/... Contains the software suite we're building
And the file we're looking at is in:
/home/project/the_system/core_app/interface/src/messaging.c
Which itself is included by maybe 5 other sources, like:
/home/project/the_system/core_app/interface/src/sys-control.c
/home/project/the_system/core_app/interface/src/file-control.c
/home/project/the_system/core_app/interface/src/audio-control.c
... you get the idea. Each of these may then be included/called by other processes wishing to communicate with each other Did I mention it's all horrible?
There are makefiles in pretty much every folder up that chain, the makefile in the local folder
/home/project/the_system/core_app/interface/src/Makefile
is something like this (I removed a few bits for clarity, ignore unreferenced objects):
INCLUDES += -I./ -I$(PUBLIC_INCLUDE_DIR) -I$(LINUXKERNEL_INSTALL_DIR)/include -I$(CMEM_INSTALL_DIR)/packages/ti/sdo/linuxutils/cmem/include -lpthreads
C_FLAGS += -Wall -g -O3
AR_FLAGS += -r
CC = $(MVTOOL_PREFIX)gcc $(INCLUDES) $(C_FLAGS) -c
AR = $(MVTOOL_PREFIX)ar
REL_EXE1 = reboot_me
REL_LIB1 = file-control.a
REL_LIB3 = share_mem.a
REL_LIB4 = sys-control.a
REL_LIB5 = msg_util.a
REL_LIB9 = messaging.a
REL_LIB10 = sysctrl.a
REL_LIB11 = audio-control.a
REL_OBJ1 = file-control.o share_mem.o msg_util.o
REL_OBJ3 = share_mem.o
REL_OBJ4 = sys-control.o share_mem.o msg_util.o
REL_OBJ5 = msg_util.o
REL_OBJ9 = messaging.o
REL_OBJ10 = sysctrl.o sys-control.o share_mem.o msg_util.o messaging.o audio-control.o
REL_OBJ11 = audio-control.o messaging.o share_mem.o msg_util.o
all: $(REL_EXE1) $(REL_LIB9) $(REL_LIB12) $(REL_LIB3) $(REL_LIB1) $(REL_LIB2) $(REL_LIB4) $(REL_LIB5) $(REL_LIB6) $(REL_LIB7) $(REL_LIB8) $(REL_LIB10) $(REL_LIB11) install
$(REL_LIB1): $(REL_OBJ1)
$(AR) $(AR_FLAGS) $(REL_LIB1) $(REL_OBJ1)
$(REL_LIB2): $(REL_OBJ2)
$(AR) $(AR_FLAGS) $(REL_LIB2) $(REL_OBJ2)
$(REL_LIB3): $(REL_OBJ3)
$(AR) $(AR_FLAGS) $(REL_LIB3) $(REL_OBJ3)
$(REL_LIB4): $(REL_OBJ4)
$(AR) $(AR_FLAGS) $(REL_LIB4) $(REL_OBJ4)
$(REL_LIB5): $(REL_OBJ5)
$(AR) $(AR_FLAGS) $(REL_LIB5) $(REL_OBJ5)
$(REL_LIB7): $(REL_OBJ7)
$(AR) $(AR_FLAGS) $(REL_LIB7) $(REL_OBJ7)
$(REL_LIB8): $(REL_OBJ8)
$(AR) $(AR_FLAGS) $(REL_LIB8) $(REL_OBJ8)
$(REL_LIB9): $(REL_OBJ9)
$(AR) $(AR_FLAGS) $(REL_LIB9) $(REL_OBJ9)
$(REL_LIB10): $(REL_OBJ10)
$(AR) $(AR_FLAGS) $(REL_LIB10) $(REL_OBJ10)
$(REL_LIB11): $(REL_OBJ11)
$(AR) $(AR_FLAGS) $(REL_LIB11) $(REL_OBJ11)
$(REL_LIB12): $(REL_OBJ12)
$(AR) $(AR_FLAGS) $(REL_LIB12) $(REL_OBJ12)
file-control.o : file-control.c $(PUBLIC_INCLUDE_DIR)/file-control.h $(PUBLIC_INCLUDE_DIR)/Msg_Def.h\
$(PUBLIC_INCLUDE_DIR)/sys_env_type.h
$(CC) $(C_FLAGS) -o $# $<
audio-control.o : audio-control.c $(PUBLIC_INCLUDE_DIR)/audio-control.h \
$(PUBLIC_INCLUDE_DIR)/Msg_Def.h $(PUBLIC_INCLUDE_DIR)/sys_env_type.h
$(CC) $(C_FLAGS) -o $# $<
share_mem.o: share_mem.c $(PUBLIC_INCLUDE_DIR)/share_mem.h
$(CC) $(C_FLAGS) -o $# $<
sys-control.o : sys-control.c $(PUBLIC_INCLUDE_DIR)/sys-control.h $(PUBLIC_INCLUDE_DIR)/Msg_Def.h\
$(PUBLIC_INCLUDE_DIR)/sys_env_type.h $(PUBLIC_INCLUDE_DIR)/share_mem.h
$(CC) $(C_FLAGS) -o $# $<
msg_util.o: msg_util.c $(PUBLIC_INCLUDE_DIR)/Msg_Def.h
$(CC) $(C_FLAGS) -o $# $<
messaging.o: messaging.c $(PUBLIC_INCLUDE_DIR)/messaging.h
$(CC) $(C_FLAGS) -o $# $<
sysctrl.o: sysctrl.c $(PUBLIC_INCLUDE_DIR)/sysctrl.h $(PUBLIC_INCLUDE_DIR)/sys_env_type.h
$(CC) $(C_FLAGS) -o $# $<
reboot_me:
$(MVTOOL_PREFIX)gcc -g -Wall -static -c -o reboot_me.o reboot_me.c
$(MVTOOL_PREFIX)gcc -o reboot_me reboot_me.o
clean:
-$(RM) -f *.o
-$(RM) -f *.a
-$(RM) -f $(REL_EXE1)
-$(RM) -Rf $(APP_LIB_DIR)
install: $(REL_EXE1) $(REL_LIB3) $(REL_LIB1) $(REL_LIB2) $(REL_LIB4) $(REL_LIB5) $(REL_LIB7)
install -d $(APP_LIB_DIR)
install $(REL_LIB1) $(APP_LIB_DIR)
install $(REL_LIB2) $(APP_LIB_DIR)
install $(REL_LIB3) $(APP_LIB_DIR)
install $(REL_LIB4) $(APP_LIB_DIR)
install $(REL_LIB5) $(APP_LIB_DIR)
install $(REL_LIB7) $(APP_LIB_DIR)
install $(REL_LIB8) $(APP_LIB_DIR)
install $(REL_LIB9) $(APP_LIB_DIR)
install $(REL_LIB10) $(APP_LIB_DIR)
install $(REL_LIB11) $(APP_LIB_DIR)
install $(REL_LIB12) $(APP_LIB_DIR)
install $(REL_EXE1) $(EXEC_DIR)
Anyway, having added
#include <semaphore.h>
to the top of
/home/project/the_system/core_app/interface/src/messaging.c
what do I need to do to allow this to compile properly?
As a bonus question, is there any way to determine which one of:
-pthread
-lpthread
-lpthreads
-lrt
-rt
Is the correct one for our particular build environment?
Edit to add (also TL;DR):
I seem to be encountering an exact duplicate of the scenario mentioned in this question.
However, no matter where I stick the -lpthread and -lrt arguments I get errors.
For example, I tried to add a call to pthread_mutex_trylock, and it fails to compile:
undefined reference to 'pthread_mutex_trylock'
...even though existing functions calling pthread_mutex_lock compile OK.
I am not sure exactly what you mean by the first question. I will attempt to cover all possibilities.
The answer to the second question was pretty much covered by Joachim.
Your system will attempt to build messaging.o if you change messaging.c, for example, if you add a header file to the top.
If you want to know, how to succeed that attempt, well, you need to provide the proper location of the file semaphore.h in the INCLUDES variable. It is a "system" file, in one of the "system" include directories.
If you want to ensure, that you rebuild messaging.o when semaphore.h changed, you would need to read the section on advanced auto-dependency generation in the GNU Make Manual or on MadScientist's site http://mad-scientist.net/make/autodep.html
Or, use the ElectricAccelerator, that EricMelski talks about all the time. That fantastic software, has automatic dependency generation built-in for free. You don't have to do a thing.
Also, as you already know, the Makefile you are showing is very poorly written, very "naiive". And it sounds like you have a recursive system of several thousand of similarly poor Makefiles. Yes, it is terrible.
And it sounds like you personally do not want to fix this build system as such, you are just interested to add some functionality to the software itself.
So, I think you need to hire an expert consultant to write your company a state-of-the-art system, perhaps using ElectricAccelerator, or plain old GNU Make. Do you get the hint? Ehm, , if Eric can put plugs here all the time and he gets away with it, then so can I :)
Well, I finally got the hateful thing to build, unfortunately more through brute force & ignorance than some elegant master-stroke of coding genius.
However, should it help some future generation, the route I followed was this:
Add -lrt -lpthread to C_FLAGS in my example makefile, and then tried to make
When make failed, look at the location where it failed, load the makefile from that place and add -lrt -lpthread in a similar fashion in that makefile.
Lather, rinse, repeat until make succeeds.
It now seems to work OK, of course there are now 100 other bugs to fix, but at least I got it to compile in the end.
Nurse, the screens!