0

I am trying to use autotools in my Yocto project. Working with another user I was able to get bitbake to recognize my autogen.sh, configure.ac and Makefile.am. I am now getting the error

make: *** No rule to make target 'main.c', needed by 'main.o'.  Stop.

My tree is as follows:

.
├── files
│   ├── MAIN_Application
│   │   ├── autogen.sh
│   │   ├── configure.ac
│   │   ├── include
│   │   │   ├── main.h
│   │   │   ├── scheduler.h
│   │   │   └── utilities
│   │   │       └── time_conversions.h
│   │   ├── Makefile.am
│   │   ├── project.yml
│   │   └── src
│   │       ├── main.c
│   │       ├── Makefile.am
│   │       ├── scheduler.c
│   │       └── utilities
|   |           ├── Makefile.am
│   │           └── time_conversions.c
│   └── services
│       └── mainapplication.service
└── mainapplication_0.0.bb

My makefile.am is as follows:

AUTOMAKE_OPTIONS = foreign

CFLAGS = -Wall -pedantic -O2
include_HEADERS = main.h

bin_PROGRAMS = MAIN_Application
MAIN_Application_SOURCES = main.c

I believe I need to add my other source files. What I am not sure is how to do so. Do I add them with MAIN_Application_SOURCES or do I need to add a Makefile.am in each subdirectory?

Edit: Adding link to previous question. Edit 2: I have added a makefile.am to each directory. In MAIN_Application I have:

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src
    

In src I have:

AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = MAIN_Application
EVCC_Application_SOURCES = main.c scheduler.c time_conversions.c

This gives a new error:

| Making all in src
| /bin/bash: line 20: cd: src: No such file or directory
| make: *** [Makefile:332: all-recursive] Error 1
| ERROR: oe_runmake failed
            

Edit 3: If I remove my src and include folders, place everything into one folder (top level) it all works. This is ugly and I hate it.

.
├── files
│   ├── MAIN_Application
│   │   ├── autogen.sh
│   │   ├── configure.ac
│   │   ├── main.c
│   │   ├── main.h
│   │   ├── Makefile.am
│   │   ├── project.yml
│   │   ├── scheduler.c
│   │   ├── scheduler.h
│   │   ├── time_conversions.c
│   │   └── time_conversions.h
│   └── services
│       └── mainapplication.service
└── mainapplication_0.0.bb

There has to be a way around this.

Edit 4: I am attempting to move all of my code into a src directory and use SUBDIR in my makefile.am

.
├── files
│   ├── MAIN_Application
│   │   ├── autogen.sh
│   │   ├── configure.ac
│   │   ├── include
│   │   ├── Makefile.am
│   │   ├── project.yml
│   │   ├── src
│   │   │   ├── main.c
│   │   │   ├── main.h
│   │   │   ├── Makefile.am
│   │   │   ├── scheduler.c
│   │   │   ├── scheduler.h
│   │   │   ├── time_conversions.c
│   │   │   └── time_conversions.h
│   │   └── test
│   │       ├── test_scheduler.c
│   │       └── test_time_conversions.c
│   └── services
│       └── mainapplication.service
└── mainapplication_0.0.bb

This leads to the same error of src no such file or directory.

Michael
  • 399
  • 2
  • 17
  • Are all your sources going into building the one binary? No linkable libraries, no secondary programs, *etc*.? Is there a need to build any of the sources with different compiler options than others? I ask because without any of that, recursive (Auto)make is probably counterproductive for the project depicted. – John Bollinger Mar 08 '22 at 19:05
  • At this stage the project is very simple, the complexity will balloon as we progress. I realize that if I cannot get automake pointing to sources in folders at this early stage, I will never get it working. – Michael Mar 08 '22 at 19:20
  • Have you added `src/Makefile` to `AC_CONFIG_FILES` in `configure.ac`? – ndim Mar 08 '22 at 19:36
  • I was literally just posting that as my answer while you put this! I was pouring over another GitHub file and saw the line. – Michael Mar 08 '22 at 19:37

2 Answers2

1

I believe I need to add my other source files. What I am not sure is how to do so.

There is more than one way to do it, but one way or another, yes, you do need to tell Automake about all the sources involved. Depending on how you do it, you might need more than to just designate the sources.

Do I add them with MAIN_Application_SOURCES or do I need to add a Makefile.am in each subdirectory?

For the project as depicted in the question, you can, and probably should, add them to MAIN_Application_SOURCES in the top-level Makefile.am. In that case, you probably do not need any other Makefile.am files. You should provide paths relative to the directory containing the Makefile.am, so something like:

MAIN_Application_SOURCES = \
  src/main.c \
  src/scheduler.c \
  src/utilities/time_conversions.c

(It's not necessary to use the one-per-line format above, but I find that a lot easier to read and maintain than putting multiple filenames on one line.) In this case, you probably also want to add subdir-objects to your AUTOMAKE_OPTIONS:

AUTOMAKE_OPTIONS = foreign subdir-objects

You need more Makefile.am files only if you want more Makefiles to be generated, which ordinarily would be associated with recursive make.

Furthermore, to be useful, a Makefile.am must define at least one target to be built, and I see only one natural target in the whole project (MAIN_Application). You could introduce so-called "convenience libraries" to serve as targets for subdirectory makes, but I do not favor this approach, nor, for that matter, most uses of recursive make.


Additionally, this ...

include_HEADERS = main.h

... does not mean what you probably think it means. It says that file main.h (in, or to be generated in, the current directory) should be installed to $(includedir) by make install. It says nothing whatever about main.h's relationship to other targets. Still working on the assumption of a single top-level Makefile.am, I think what you want here is altogether different:

AM_CPPFLAGS = -I$(srcdir)/include

That will cause what appears to be an appropriate -I option to be provided to the compiler.

Supposing that you do not require support for make dist, and you do not actually want to install your header files as part of make install, you do not need to explicitly designate individual header files to Automake.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • This answer is great, really detailed. I have read it a few times now. I am having issue though. I made all of your changes but my build fails as it can not find time_conversions.h. I will post my new makefile as an edit above. – Michael Mar 09 '22 at 14:55
  • 1
    Figured it out. Added the include path. – Michael Mar 09 '22 at 15:57
0

The issue is with configure.ac! This is my new folder structure

.
├── files
│   ├── MAIN_Application
│   │   ├── autogen.sh
│   │   ├── configure.ac
│   │   ├── include
│   │   │   ├── main.h
│   │   │   ├── scheduler.h
│   │   │   └── utilities
│   │   │       └── time_conversions.h
│   │   ├── Makefile.am
│   │   ├── project.yml
│   │   ├── src
│   │   │   ├── main.c
│   │   │   ├── Makefile.am
│   │   │   ├── scheduler.c
│   │   │   └── utilities
│   │   │       └── time_conversions.c
│   │   └── test
│   │       ├── test_scheduler.c
│   │       └── test_time_conversions.c
│   └── services
│       └── mainapplication.service
└── mainapplication_0.0.bb

My top level Makefile.am contains:

AUTOMAKE_OPTIONS = foreign
SUBDIRS =  src

My Makefile.am in src contains

AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = MAIN_Application
MAIN_Application_SOURCES = main.c scheduler.c time_conversions.c

Obviously these did not change from my question above. In my configure.ac I added one item to AC_CONFIG_FILES. This line changed from

AC_CONFIG_FILES([Makefile])

to

AC_CONFIG_FILES([Makefile src/Makefile])

Anytime you use a subdirectory like this you need to tell autotools about it. I solved this by searching for similar projects on GitHub and I found this.

In this project they have a top level makefile, as well as a makefile in each subdirectory containing source files. In their configure.ac they also give a path to each makefile!

Michael
  • 399
  • 2
  • 17
  • 1
    Yes, you need to tell Autoconf about every file you want it to generate. Among other things, that means a `Makefile` corresponding to every `Makefile.am`. But you should also consider whether you really do want more than one `Makefile`. It is not (ever) necessary, and there are [reasons to prefer sticking to just one](https://grosskurth.ca/bib/1997/miller.pdf). – John Bollinger Mar 08 '22 at 19:45