How to convert a makefile into readable code? - linux

I downloaded a set of source code for a program in a book and I got a makefile.
I am quite new to Linux, and I want to know whether there is any way I can see the actual source code written in C?
Or what exactly am I to do with it?

It sounds like you may not have downloaded the complete source code from the book web site. As mentioned previously, a Makefile is only the instructions for building the source code, and the source code is normally found in additional files with names ending in .c and .h. Perhaps you could look around the book web site for more files to download?
Or, since presumably the book web site is public, let us know which one it is and somebody will be happy to point you in the right direction.

A Makefile does not contain any source itself. It is simply a list of instructions in a special format which specifies what commands should be run, and in what order, to build your program. If you want to see where the source is, your Makefile will likely contain many "filename.c"'s and "filename.h"'s. You can use grep to find all the instances of ".c" and ".h" in the file, which should correspond to the C source and header files in the project. The following command should do the trick:
grep -e '\.[ch]' Makefile
To use the Makefile to build your project, simply typing make should do something reasonable. If that doesn't do what you want, look for unindented lines ending in a colon; these are target names, and represent different arguments you can specify after "make" to build a particular part of your project, or build it in a certain way. For instance, make install, make all, and make debug are common targets.
You probably have GNU Make on your system; much more information on Makefiles can be found here.

It looks like you also need to download the SB-AllSource.zip file. Then use make (with the Makefile that you've already downloaded) to build.

Related

Include an Application Image in Yocto Build

I feel like I have done my level best to search for an answer for this but, admittedly, maybe I am not using the correct search keys.
I am building a Linux kernel using Yocto and I can see that adding lines IMAGE_INSTALL_append to local.conf, followed my the additional images that you want to include is the way that you include things like connman, dropbear, etc. That's fine.
What I want to do is include an image of the application that I have written. Let's call it HelloWorld.exe and I would like it to be tucked into it's own directory (MyHello) along with a sub-directory and the sub-directory also contains some files that are necessary for the operation of HelloWorld.
I'm sure that there are different ways of doing this but I just need one. I need to know:
Where do I position my HelloWorld.exe and its attendant files and subdirectories on my Ubuntu system where they will be picked up during the build and included in the image?
How do I alter local.conf to ensure that the final image will include my application and its support files and directories where I need it to be on the target?
Thank you. Mark
I believe it gets a bit complicated in Yocto:
You need to create your own layer. Let's say meta-hello. This folder needs to in the same place as all your other meta layers and also where your poky directory is.
You need to enable that layer in your bblayers.conf file. For that you can use bitbake-layers add-layer /path/to/meta-hello
Now within your meta-hello create a recipe in a folder recipes-hello/hello
your hello.bb file is within the above mentioned folder and your can decide to use either automake, makefile or compile it accordingly using the Dev Manual Here
Once that is done, in your BUILD dir perform bitbake hello and this will compile and provide errors if any. Resolve them and once it compiles successfully, add IMAGE_INSTALL_append = " hello" in the local.conf file.
This is one way of doing it. Another one is a bit complex using the ADT Yocto Workflow
Sorry to say there is no easier way around this as Yocto does have a steep learning and development curve.
Practical Example
You can look at this blog post by Boundary Devices which creates a simple daemonize automake example. You can find it on GitHub too.
devtools workflow
Youtube Video by Tim Orling from Intel on devtools workflow
packing external binaries
For this case use Binaries Installation in Mega Manual

How to tell SCons to stop computing implicit dependencies in a particular directory?

My SCons project depends on a lot of third party libs, each providing dozens or hundreds of include files.
My understanding of how SCons works is that, on each build, it parses the source files of my project to find the #include directives, and it uses the value of env['CPPPATH'] to find these files and compute their md5 sum.
This scanning is costly, and thus I would like to optimize this process by teaching SCons that all the headers of my third party files will never change. This property is actually enforced by the tool that manages our third party libs.
I know there is a --implicit-deps-unchanged option that forces scons to assume that the implicit dependencies did not change, but it works globally. I did not find a way to restrict this option to a particular directory. I tried to find if the default Scanner of implicit C++ files can be configured, but found nothing. I think it is possible to avoid using CPPPATH, and instead only give the -I option to the compiler directly, but it is cumbersome.
Is there any way to optimize SCons by teaching him that files in a directory will never, ever change?
You can try pre-expanding the list of header file paths into CCFLAGS.
Note that doing so means they will not be scanned.
for i in list_of_third_party_header_directories:
env['CCFLAGS'].append('-I' + i)
In this case the contents of CPPPATH would be your source directories, and not the third-party ones which you assert don't change.
Note that changing the command line of your compile commands in any way (unless the arguments are enclosed in $( $)) will cause your source files to recompile.

CMake and Visual Studio - Specify solution file directory

I've defined a CMakeLists.txt file for my project which works correctly.
I use the CMake GUI for generating a Visual Studio Project, and I ask to build the binaries (CMAke cache and other stuff) in the folder Build which is in the same folder where CMakeLists.txt is.
I was able to specify where the executable and the libraries have to be created.
Is there a way to specify also where the Visual Studio Solution file has to be created? I would like to have it in the root directory, but at the same time I don't want to have also all the other files that CMake creates in the Build directory.
CMake creates the Project I defined in CMakeLists.txt but also two other projects: ALL_BUILD and ZERO_CHECK. What's their utility?
I was able to avoid the creation of ZERO_CHECK by using the command set_property(GLOBAL PROPERTY USE_FOLDERS On).
Is there a way for avoiding also the creation of ALL_BUILD?
It seems you only switched to CMake very recently, as exactly those questions also popped into my head when I first started using CMake. Let's address them in the order you posted them:
I use the CMake GUI for generating a Visual Studio Project, and I ask
to build the binaries (CMAke cache and other stuff) in the folder
Build which is in the same folder where CMakeLists.txt is.
Don't. Always do an out-of-source build with CMake. I know, it feels weird when you do it the first time, but trust me: Once you get used to it, you'll never want to go back.
Besides the fact that using source control becomes so much more convenient when code and build files are properly separated, this also allows to build separate distinct build configurations from the same source tree at the same time.
Is there a way to specify also where the Visual Studio Solution file has to be created?
You really shouldn't care.
I see why you do feel that you need full control over how the solution and project files get created, but you really don't. Simply specify the target for the solution as the origin of your out-of-source build and forget about all the other files that are generated. You don't need to worry, and you don't want to worry - this is exactly the kind of stuff that CMake is supposed to take care of for you.
Ask yourself: What would you gain if you could handpick the location of every project file? Nothing, because chances are, you will never touch them anyways. CMake is your sole master now...
CMake creates the Project I defined in CMakeLists.txt but also two
other projects: ALL_BUILD and ZERO_CHECK. What's their utility? I was
able to avoid the creation of ZERO_CHECK by using the command
set_property(GLOBAL PROPERTY USE_FOLDERS On). Is there a way for
avoiding also the creation of ALL_BUILD?
Again, you really shouldn't care. CMake defines a couple of dummy projects which are very useful for certain internal voodoo that you don't want to worry about. They look weird at first, but you'll get used to their sight faster than you think. Just don't try to throw them out, as it won't work properly.
If their sight really annoys you that much, consider moving them to a folder inside the solution so that you don't have to look at them all the time.
Bottom line: CMake feels different than a handcrafted VS solution in a couple of ways. This takes some getting used to, but is ultimately a much less painful experience than one might fear.
You don't always have a choice about what your environment requires. Visual Studio's GitHub integration requires that the solution file exists in source control and is at the root of the source tree. It's a documented limitation.
The best I was able to come up with is adding this bit to CMakeList.txt:
# The solution file isn't generated until after this script finishes,
# which means that:
# - it might not exist (if this is the first run)
# - you need to run cmake twice to ensure any new solution was copied
set(sln_binpath ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.sln)
if(EXISTS ${sln_binpath})
# Load solution file from bin-dir and change the relative references to
# project files so that the in memory copy is as if it had been built in
# the source dir.
file(RELATIVE_PATH prefix
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
file(READ ${sln_binpath} sln_content)
string(REGEX REPLACE
"\"([^\"]+).vcxproj\""
"\"${prefix}/\\1.vcxproj\""
sln_content
"${sln_content}")
# Compare the updated contents with the existing source path sln, if it
# exists and is the same we don't want to disturb VS by touching it.
set(sln_srcpath ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.sln)
set(old_content "")
if(EXISTS ${sln_srcpath})
file(READ ${sln_srcpath} old_content)
endif()
if(NOT old_content STREQUAL sln_content)
file(WRITE ${sln_srcpath} ${sln_content})
endif()
endif()
What would be helpful is if cmake had a way to run post generation scripts, but I couldn't find one.
Other ideas that didn't work out:
wrap cmake inside a script that does the same thing, but:
telling users to run a seperate script isn't simpler than saying to run cmake twice. Especially since needing to run cmake twice isn't a foreign concept.
put it in a pre-build step, but
building is common and changing the build is rare
changing the solution from builds inside the IDE makes it do... things
use add_subdirectory because that's suppose to finish first
it appeared to make the vcxproj's immediately, but not the sln until later, but I didn't try as hard because this adds a bunch of additional clutter I didn't want - so maybe this can be made to work

Can configure generate .h files?

On Linux, when I execute ./configure it generates header files and also .c files (besides Makefiles), right? How can I get configure to do that?
You will probably want to create a configure.ac (but depend on the autoconf version), but read here, to give you an idea what should you create and what is auto generated. It has good covered on the autotools topic.
It's typically used to generate config header, that contains various defines (often libraries & function present or not). But this happens only if autotools were instructed to create configure doing that.
You define what goes to (and to which header exactly) in configure.ac (input file to autotools). See AC_CONFIG_HEADERS, AC_CHECK_HEADER, AC_CHECK_LIB and similar macros. See autoconf manual for details. Also read through complete tutorial jasonw linked. And see how things are done in some existing projects.

How to get a configure script to look for a library

I'm trying to write a configure.ac file such that the resulting configure script searches for a library directory containing a given static library e.g. libsomething.a. How can I do this? At the moment I have it check just one location with:
AC_CHECK_FILE([/usr/local/lib/libsomething.a],[AC_SUBST(libsomething,"-L/usr/local/lib -lsomething")],[AC_SUBST(libcfitsio,'')])
But I want it to try and find it automatically. And if the library isn't in one of the default locations, I'd like configure to say that the library wasn't found and that a custom location can be specified with --use-something=path as is usually done. So I also need to then check if --use-something=path is provided. I'm pretty new at creating configure files, and the M4 documentation isn't very easy to follow, so would appreciate any help.
Thanks!
It's not the job of configure to search where libraries are installed. it should only make sure they are available to the linker. If the user installed them in a different location, he knows how to call ./configure CPPFLAGS=-I/the/location/include LDFLAGS=-L/the/location/lib so that the tools will find the library (this is explained in the --help output of configure and in the standard INSTALL file).
Also --with-package and --enable-package macros are not supposed to be used to specify paths, contrary to what many third-party macros will do. The GNU Coding Standards explicitly prohibit this usage:
Do not use a --with option to
specify the file name to use to find
certain files. That is outside the scope
of what --with options are for.
CPPFLAGS and LDFLAGS are already here to address the problem, so why redevelop and maintain another mechanism?
The best way to figure this out is to look at other autoconf macros that do something similar. Autoconf macros are an amalgam of Bourne shell script and M4 code, so they can literally solve any computable problem.
Here's a link to a macro I wrote for MySQL++ that does this: mysql++.m4.

Resources