Makefile examples and/or templates - makefile

After some time using make to build C++ programs I still don't have a very good knowledge about Makefiles. I am thinking about asking for a "good" example and use it from now on. I have been searching, but the ones I found is too complicated for me to understand. Please give me a template, with comments explaining how it works.
Thanks.

Makefiles have the tendency to get really hairy really fast, particularly when working with multiple directories. Many of the Makefile I came across in my professional life where little more then glorified shell scripts with the dependency part mostly non existent. This kind of problems were noted by the seminal paper recursive make considered harmful.
There, and in a following article Implementing non-recursive make -- you can find a reasonable template.
Also here and here on SO you can find people searching for the illusive Makefile(s) template.
Typically, the good Makefile I have seen where the result of an expert that worked for several months and created an infrastructure that transformed the Makefile syntax into something almost completely different. The developers just needed to make assignment to special variables, include the magic code, and build.
The next step in this evolution, is a more modern tool such as CMake. CMake will generate well formed Makefiles for you. If you have control over it, please consider such a tool.
IMHO you will find it makes much more sense, and make you much more productive, give you the added value of cross platform and support the entire build process (including configuration, packaging, Continuous Integration etc.)

Related

Why does FetchContent prefer subdirectory-subsumption vs installation of dependencies?

Consider two software projects, proj_a and proj_b, with the latter depending on the former; and with both using CMake.
When reading about modern CMake, one gets the message that the "appropriate" way to express dependencies is via target dependencies; and one should arrange it so that dependent projects are represented as (imported) targets you can depend on. More specifically, in our example, proj_b will idiomatically have:
find_package(proj_a)
# etc etc.
target_link_library(bar proj_a::foo)
and proj_a will need to have been installed, utilizing the CMake installation-and-export-related commands, someplace where proj_b's CMake invocation will search for proj_a-config.cmake.
I like this approach and encourage others to adapt to it. It offers flexibility in the choice of your own version of proj_a vs the system version; and also allows for non-CMake proj_a's via a Findproj_a.cmake script (which again, can be system-level or part of proj_b).
So far so good, right? However, there are people who want to "take matters into their own hands" in terms of dependencies - and CMake officially condones this, with commands such as ExternalProject and more recently, FetchContent: This allows proj_b's configuration stage to actually download a (built, or in our case source-form) version of proj_a.
The puzzling part to me is that, after proj_a is downloaded, say to an external/proj_a directory, CMake's default behavior will be to
add_subdirectory(external/proj_a)
that is, to use proj_a as a subproject of proj_b and build them together. This, while the idiomatic use above allows the maintainer of proj_a to "do their own thing" in my CMakeFile, and only keep things neat and tidy for others via what I export/install.
My questions:
Why does it make sense to add_subdirectory(), rather than to build, install, and perform the equivalent of find_package() to meet the dependency? Or rather, why should the former, rather than the latter, be the default?
Should I really have to write my project-level CMakeLists.txt to be compatible with being add_subdirectory()'ed?
Note: Just to give some concrete examples of how this use constrains proj_a:
Must use unique option names which can't possibly clash with super-project names. So no more WITH_TESTS, BUILD_STATIC_LIB - it has to be: WITH_PROJ_A_TESTS and BUILD_PROJ_A_STATIC_LIB.
You have to account for the parent project having searched for other dependencies already, and perhaps differently than how you would like to search for them.
Following the discussion in comments, I decided to post a bug report about this:
#22904: Support FetchContent_MakeAvailable performing build+install+find_package rather than add_subdirectory
So maybe this will change and the question becomes moot.
Why does it make sense to add_subdirectory(), rather than to build, install, and perform the equivalent of find_package() to meet the dependency? Or rather, why should the former, rather than the latter, be the default?
FetchContent doesn't just have to be for project() dependencies. It can be used for fetching utility scripts too. I'm guessing it was designed with that kind of consideration in mind. If your utility script is just one file, you can just file(DOWNLOAD) and add_subdirectory() directly, but the utilities could be multiple files, such as is the case with aminaya/project_options. FetchContent() uses a lot of the same machinery as ExternalProject, so it can do a lot of the useful things that ExternalProject does. For example, you can use FetchContent to fetch aminaya/project_options as a remote git repo, or as its archive artifacts- ex. v0.20.0.zip
Should I really have to write my project-level CMakeLists.txt to be compatible with being add_subdirectory()'ed?
It's your choice! The reasoning here can be highly objective, or subjective. It's up to you. Some people just like to put in a lot of effort to support whatever their users might want. Some people have a lot of historical configuration baggage and are still catching up to newer CMake. And as you mentioned at the end of your question post, there are certain adjustments that need to be made to accomodate for cleanly allowing people to add_subdirectory() you as a dependency. One example of a project which chose "no" is glew (see issue #314 for explanation).
Just to give another reference to some related work mentioned in responses to the KitWare/CMake ticket your raised, here's the ticket which tracked work on "FetchContent and find_package() integration".

Can a project support both Autotools and Cmake at the same time?

I happen to think (but maybe is a myth) that Cmake is greater than Autotools about making easy supporting Microsoft.
At the same time, I'm kind of sure that Autotools is even more straightforward than Cmake when it comes to important UNIX derivatives such as macOS and most popular Linux distros.
What if I can't choose?
Can a project support both Autotools and Cmake at the same time?
Bonus for: can a project support both Autotools and Cmake and even simply bare Make at the same time?
By "at the same time" I mean that ideally one should not necessarily run a clean script when changing from trying one of the build systems to another. But I guess it would be a reasonable configuration, if necessary.
Finally, do you know an example project that uses both Autotools and Cmake? One that uses both Autotools, Cmake and simply bare Make?
Yes, you can very easily support both CMake and Autotools at the same time, since they don't overlap (that is, the files you use to create those environments are different, so you can have both types of files in your project at the same time). One example of this is the GNU uCommon C++ framework.
No, you can't (easily) support bare make and either of the above systems at the same time. Neither Autotools nor CMake are actually build tools themselves. They're "build tool generators". So you don't run autotools or cmake and the result is your built project: instead you run autotools or cmake and they generate control files for a build tool. Then you run the build tool and the result is your built project.
Autotools generates makefiles, and cmake generates many different types of control files, where makefiles are one of the most common.
So, you can't have your OWN makefile in your project, because they'll conflict with the makefile generated by autotools or cmake.
Of course, you can do things like put your own makefiles in a subdirectory then invoke make with an argument like make -f rawmake/makefile or something like that. But there's no convenient way to support them all.
Realistically, I would never choose to support more than one of the above options. You will spend a lot of time getting it right, and every time you need to change your build environment it's two or three times as much work. People will find issues with whichever one of them you tend to use less often. It's a huge hassle for not that much benefit.
Which you choose depends a lot on your project. If your project runs only (or almost exclusively) on POSIX-type systems, you want it to be maximally portable even to much older systems even though it uses a lot of special OS features, or you want its installation and build options to be extremely flexible (straightforward support for cross-compilation, etc.) then autotools is a good choice. If your project runs on lots of different OS types (Windows in particular) and you want people to be able to develop with their choice of IDE (Visual Studio, Xcode, etc.) easily, then cmake is a good choice.
If your program is straightforward to build and needs hardly any configuration or customization, or you are already familiar with makefiles and don't feel like learning a whole new language just for builds, then raw makefiles may be a good choice.

How to protect (obsfucate) Go binary from cracking

I wish to sell Go application. I will provide serial number to my clients. Is there ways to make it a bit more complex to crack app?
I say it is complex to crack C app and it is easy to crack Java app. Is there tools that will make Go app cracking job as hard as cracking C app? or some tutorial? At least something I could do to protect my project a bit. I do not ask about super heavy protection.
Once you have the binary itself, obfuscation is pretty difficult. People have tried stripping the symbols out of Go binaries before, but it usually leads to instability and unpredictable behavior, since symbols are required for certain reflection operations.
While you can't necessarily obfuscate the libraries you're statically linking against, you can certainly obfuscate your /own/ code by changing variable, type, and function names prior to compilation to names that are meaningless. If you want to go one step further, you can try obtaining the source code for the libraries you're using (the source code for the standard libraries is available and is included in most Go installations), and applying this obfuscation to the library source code as well.
As for post-compilation binary modification, as I mentioned before, it's probably best to stay away from it.
To add on joshlf13's answer: while stripping Go binaries is not recommended, there's a flag you can pass to the linker to omit the debugging symbols all along:
Pass the '-s' flag to the linker to omit the debug information (for example, go build -ldflags "-s" prog.go).
(Debugging Go Code with GDB)
This should at least be a better way, since I haven't seen any warnings for this like the ones about stripping symbols post-compilation.
Another option, with Go 1.16+ (Feb. 2021:
burrowers/garble
Produce a binary that works as well as a regular build, but that has as little information about the original source code as possible.
The tool is designed to be:
Coupled with cmd/go, to support modules and build caching
Deterministic and reproducible, given the same initial source code
Reversible given the original source, to de-obfuscate panic stack traces
That might not be obfuscated enough for your need, but it is a good start.

What are the major differences between makefile and CMakeList

I've searched for the major differences between makefile and CMakeLists, but found weak differences such as CMake automates dependency resolution whereas Make is manual.
I'm seeking major differences, what are some pros and cons of me migrating to CMake?
You can compare CMake with Autotools. It makes more sense! If you do this then you can find out the shortcomings of make that form the reason for the creation of Autotools and the obvious advantages of CMake over make.
Autoconf solves an important problem—reliable discovery of system-specific build and runtime information—but this is only one piece of the puzzle for the development of portable software. To this end, the GNU project has developed a suite of integrated utilities to finish the job Autoconf started: the GNU build system, whose most important components are Autoconf, Automake, and Libtool.
Make can't do that. Not out of the box anyway. You can make it do it but it would take a lot of time maintaining it across platforms.
CMake solves the same problem (and more) but has a few advantages over GNU Build System.
The language used to write CMakeLists.txt files is readable and easier to understand.
It doesn't only rely on make to build the project. It supports multiple generators like Visual Studio, Xcode, Eclipse etc.
When comparing CMake with make there are several more advantages of using CMake:
Cross platform discovery of system libraries.
Automatic discovery and configuration of the toolchain.
Easier to compile your files into a shared library in a platform agnostic way, and in general easier to use than make.
Overall CMake is clearly the choice when compared to make but you should be aware of a few things.
CMake does more than just make so it can be more complex. In the long run it pays to learn how to use it but if you have just a small project on only one platform, then maybe make can do a better job.
The documentation of CMake can seem terse at first. There are tutorials out there but there are a lot of aspects to cover and they don't do a really good job at covering it all. So you'll find only introductory stuff mostly. You'll have to figure out the rest from the documentation and real life examples: there are a lot of open source projects using CMake, so you can study them.

How to quickly remove all the unused variables with xCode?

I was wondering if there is a quick and effective way to remove all the unused variables (local, instance, even properties) in xcode... I am doing a code cleanup on my app and if I knew a quick way for code refactoring it would help me a lot...
Thanks...
It's being a long time since you made your question and maybe you found an answer already, but from an answer to a related question:
For static analysis, I strongly
recommend the Clang Static Analyzer
(which is happily built into Xcode 3.2
on Snow Leopard). Among all its other
virtues, this tool can trace code
paths an identify chunks of code that
cannot possibly be executed, and
should either be removed or the
surrounding code should be fixed so
that it can be called.
For dynamic analysis, I use gcov (with
unit testing) to identify which code
is actually executed. Coverage reports
(read with something like CoverStory)
reveal un-executed code, which —
coupled with manual examination and
testing — can help identify code that
may be dead. You do have to tweak some
setting and run gcov manually on your
binaries. I used this blog post to get
started.
Both methodologies are exactly for what you want, detecting unused code (both variables and methods) and removing them.

Resources