Get compilation info of an installed program - c

I need to obtain the information on the C-compiler used to build an installed program. I am guessing a rt or a lib can report that, but nothing concrete. Not that the program would be installed in /usr/... or a similar place, and hence would not have access to the build directory to get the relevant info.

Well behaved programs should understand the --version argument.
Packaged programs (i.e. those installed with dpkg -i or apt-get install of a .deb package on Debian, etc...) also know their package version and source.
You might try to use strings on the binary executable. However, such meta-data (about the version of the C compiler used to build the program) might have been stripped (e.g. by the strip command).
If you are developing the program (i.e. its C source code) and can change it, you might consider adding something like
timestamp.c: Makefile
echo 'const char timestamp[]=' > $#
date +'"built with $(shell $(CC) --version) on %c";' >> $#
yourprogram: $(OBJECTS) timestamp.o
$(LINK.c) $(LDFLAGS) $< -o $# $(LDLIBES)
$(RM) timestamp.c
in your Makefile (details could be wrong, but you get the idea)

Related

Compatibility between versions of GNU Make

I have been using GCC for many years to compile ARM projects developed using Eclipse. I have decided it is time to update the tools I'm using.
I have been using a version of GCC 'cribbed' from CodeSourcery, but I have upgraded to the latest version from http://gnutoolchains.com/arm-eabi/. All works well, except for Make:
The CodeSourcery folder includes a version named cs-make.exe, dated 30/04/2013. I have downloaded a newer version of GCC/GDB from http://gnutoolchains.com/arm-eabi/ into a folder that I named SysGCC. It contains the app make.exe, dated 27/05/2015.
I have modified my makefile to use SysGCC and it compiles correctly. However, if I then modify my project to run make.exe instead of cs-make.exe the console shows the following errors:
make -j -k all
make: *** No rule to make target `IO.o', needed by `Display.elf'.
make: *** No rule to make target `XTPcommon.o', needed by `Display.elf'.
make: *** No rule to make target `DisplayCommon.o', needed by `Display.elf'.
.
.
The contents of my makefile are quite complex, and include the following:
%.o : %.c makefile
$(COMPILE) -c $(CFLAGS) $< -o $(OUTPUT_FOLDER)/$#
$(COMPILE) -MM $(CFLAGS) $< > $(OUTPUT_FOLDER)/$(addsuffix .d, $(notdir $(basename $#)))
Since they build correctly with cs-make.exe I can see no reason why they shouldn't build with make.exe. So, what's going wrong?
Thank you both for your responses.
I spent many frustrating hours trying different combinations of GCC, OpenOCD, JTag drivers and Eclipse plug-ins. I have numerous build versions of a project that all work with my previous toolchain and I tried copying various of these into the project I use to test the new toolchain.
I eventually found the solution. I had somehow managed to corrupt my project to use source files from one build version and a makefile from another version, and there were incompatibility issues between them.
The symptoms were very deceptive and led me up various blind alleys. I still can't understand why it worked with one version of make but not with the other.
When I corrected the project everything worked correctly.

Xcode 7.1 not linking from /usr/local/lib library

I am building a Swift command-line application with references to a third party library (netcdf) in /usr/local/lib. I have a bridging header in the project and when making the appropriate calls, there are no errors. So I'm fairly confident that the #include is being found in the bridging file.
In Build Settings, I have added /usr/local/lib to Library Search Paths and -lnetcdf to Other Linker Flags.
However I am seeing a link failure. Specifically I am seeing an undefined symbols message. Looking at the ld command shown when I click on the error, I can see that -L/usr/local/lib is there. However the -lnetcdf is not.
What else do I have to do to get the -l into the link command?
After three hours of trying to resolve this, I eventually thought 'stuff it' and spent about 15 mins writing a Makefile.
CLIBS=-lnetcdf
SWFILES=main.swift NCUtil.swift
SWIMPORT=-import-objc-header ../GSIP-Bridging-Header.h
SWIFTLIB=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx
SLIBS=-lSystem -lobjc
GSIP: main.o NCUtil.o
ld $^ -arch x86_64 -L $(SWIFTLIB) $(SLIBS) $(CLIBS) -rpath $(SWIFTLIB) -macosx_version_min 10.10 -no_objc_category_merging -o $#
%.o: %.swift
swiftc -c $(SWFILES) -target x86_64-apple-darwin14.5.0 -I /usr/local/include -I /usr/include $(SWIMPORT) -module-name=GSIP
.PHONY: clean
clean:
rm -f *.o GSIP
There is in fact another solution. Using the Finder menu to Go -> Go to Folder, go to the directory where the dylib is located. Then from Finder, drop and drag the dylib into your project. Probably a wise idea to use a reference rather than make a copy of the file.
This resolved all my link errors!

Compiling C program that uses a library

I've made a C program that uses libsndfile to extract some data from audio files.
What possibilities are there to make the program as portable as possible, preferably without requiring root access when installing?
Libsndfile is not available at the target machines, so i need to somehow package it with my program. Is there a way to statically link the library? I've also looked at some Autotools tutorials, but I'm not sure how to proceed.
I can compile without a hitch on my dev machine, where I installed the libraries using the package manager: apt-get install libsnfile1-dev
The makefile is very simple:
CFLAGS=-std=c99 -Wall -pedantic -g
CLIBS= -lsndfile -lm
BIN=audiodecode
CC=gcc
MAIN=main.o
FILES=
OBJS=$(FILES) $(MAIN)
.PHONY: all
all: clean $(OBJS)
$(CC) $(CFLAGS) -o $(BIN) $(OBJS) $(CLIBS)
.PHONY: clean
clean:
rm -f *.o $(BIN)
A lot of packages bundle their dependencies. Examples: rsync (contains a bundled libpopt), gnupg (contains a bundled libz). Other dependencies commonly bundled are gettext or glib.
For inspiration look at how these popular open source projects do it.
Put the content of http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.25.tar.gz into a subdir and add apropriate rules to build the the subdir first.
Untested sample code:
OBJS += libsndfile/libsndfile.a
libsndfile/libsndfile.a:
cd libsdndfile && ./configure --enable-static && $(MAKE)
For Bonus points add a configure script, that check if the system has already installed libsndfile and link to it dynamically.

Cross compiling source from windows to linux

This is my make file
EXE = signsrch
CFLAGS += -s -O2
PREFIX = /usr/local
BINDIR = $(PREFIX)/bin
SRC = $(EXE).c
all:
$(CC) $(CFLAGS) -c disasm.c
$(CC) $(CFLAGS) -c asmserv.c
$(CC) $(SRC) $(CFLAGS) -o $(EXE) *.o
install:
install -m 755 -d $(BINDIR)
install -m 755 $(EXE) $(BINDIR)/$(EXE)
.PHONY:
install
I want to cross compile it for my ubuntu and I tried:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
but I get unknown type name errors with a bunch of âDWORDâ
Help?
We also need to see some code, but....
Windows has its own types for basic things above the vanilla C ones, as does Linux. It sounds like DWORD as a type is not known in Linux (likely). You'll probably have to create a mytypes.h file that redefines Windows standards like DWORD into Linux speak when building for a Linux platform. Linux has types.h that defines things like int32_t which is the equivalent. See this thread for more about this.
I've assumed you have a working cross compiler set up and you're fighting just with the port. If you haven't, that's your first job. You could have a windows based compiler that targets Linux (the cygwin option, mentioned in another post) or go for a Linux based compiler and targetting windows (crosstool will help here). Though since you seem to be targetting arm, I'm expecting that that Ubuntu install isn't the place you wish to build! :-)
to cross compile you need a toolchain for the target platform, not just a Makefile. Check this tutorial and also Cygwin

First C programm - need help with eclipse

I have install the C/C++ CDT Version of Eclipse. After making a HelloWorld.c file and get the code in there I get an error of "Launch failed. Binary not found".
I found in google that my Eclipse miss the compiler and I install MinGW on my computer and add the path to env variables (tested it with "gcc -v" in cmd and succeded).
1) I can build now, but have no idea how to make a MAKEFILE. - I Read 10 tutorials but don't understand it - ideas?
2) I can build, but not run, I get "Launch failed. Binary not found" - ideas?
Found the error: I never maked a ".c" file -.- after renaming it - works fine.
Revised answer: If you want to avoid writing a real makefile, you can write something like this:
all:
gcc *.c -o runme.exe
You need to specify the binary which gcc outputs (gcc [..] -o <this one>) in the run settings (in the previous example, it should point to runme.exe). Go to Run->Run Configurations, and under C/C++ Application browse and look for runme.exe.
I would, however, strongly advise you to seriously learn about makefile. The beauty of makefiles is that you can use very little features at first and use more and more as you go on (as you saw, writing a "dummy" file was very quick). At first I suggest you write something a bit more "clever" than what I gave you above. Here's a nice tutorial and an example:
all: hello
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello
main.o: main.cpp
g++ -c main.cpp
factorial.o: factorial.cpp
g++ -c factorial.cpp
hello.o: hello.cpp
g++ -c hello.cpp
clean:
rm -rf *o hello
all is what compiles at default. What comes before the : are rule names and after it are the dependencies. i.e, to compile all you need to compile hello (though only if it's been updated), and so forth. the line below the rule is the command to compile. I hope this helps. Please read the tutorial, Makefiles are important.
Add the directory that gcc resides in (C:\MinGW\bin or whatever) to your PATH environment variable and restart Eclipse (important!). This is the process in XP: http://vlaurie.com/computers2/Articles/environment.htm. That should sort it out.
1 I suggest you to take a look at this:
http://www-scf.usc.edu/~csci410/handouts/make.pdf
It's a basic gmake tutorial and should be enough to get you started. But right now, for single file project, I suggest you to just skip creating Makefiles and doing in the command prompt:
gcc -o helloworld.exe helloworld.c
And running your executable in the prompt. You can worry about Makefiles later in your learning curve.
2 How did you setup your project?
Make sure you've got a binary parser selected when you bring up properties for the project. At least in my install, none were checked by default. I needed to check Mach-O 64 parser; you'll need to pick one based on what you're doing. I picked this up from http://www.thexploit.com/tools/os-x-10-6-64-bit-eclipse-cdt-missing-binaries/
I didn't have a binary parser selected, and that seems to mean that CDT can't find anything that it recognizes as a binary. It meant in my case that I just got the "Launch failed. Binary not found" message, even though I specified the exact binary, including a fully-qualified path, in the run/debug configurations.
This has nothing to do with builds, just running/debugging. If you're having a problem building, this probably is irrelevant.

Resources