Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8744759
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T11:53:39+00:00 2026-06-13T11:53:39+00:00

I suspect that the manual is actually saying what I’m doing wrong, but I

  • 0

I suspect that the manual is actually saying what I’m doing wrong, but I can’t really see a solution; the problem occurs when the .c file and the .o file to be build are not in the same directory, and the .c file has an automatic dependency on a .h file which has to be generated on the fly. The problem can be probably be solved by manually setting dependencies between the .c and .h file, but I would like to avoid that.

I have the following directory structure:

weird/
    Jamfile
    b.c
    src/
        a.c
        c.c

The src/a.c file is like this:

#include "src/a.h"

int main(int argc, char *argv[])
{
    return 0;
}

The b.c file is like this:

#include "src/b.h"

int main(int argc, char *argv[])
{
    return 0;
}

The src/c.c file is like this:

#include "c.h"

int main(int argc, char *argv[])
{
    return 0;
}

The Jamfile is:

rule CreateHeader
{
    Clean clean : $(1) ;
}

actions CreateHeader
{
    echo "int x = 10;" > $(1)
}

Object a.o : src/a.c ;
Object b.o : b.c ;
Object c.o : src/c.c ;

CreateHeader src/a.h ;
CreateHeader src/b.h ;
CreateHeader src/c.h ;

The following command correctly creates b.o and src/b.h:

jam b.o

The following command creates src/a.h, but then GCC fails to create a.o; the reason is quite obviously that the #include in a.c mentions src/a.h while in fact should simply refer to a.h:

jam a.o

The following command fails completely, and does not even create c.h; the reason is probably that when Jam analyzes c.c it generates a dependency on c.h instead of src/c.h, and in the Jamfile there are no rules for generating c.h:

jam c.o

This command compiles properly if I explicitly ask to generate src/c.h before asking for c.o:

jam src/c.h
jam c.o

In my opinion the jam src/c.h should not be necessary. What’s wrong here? Check the Jam manual for more information, particularly under the section Header File Scanning.

Added after I accepted the answer

I kept experimenting a little bit with the constructs suggested by the author of the accepted answer, and I’ll post here the results. In this setting you can type:

jam app

And the application will be linked under bin/app. Unfortunately I had to use a UNIX path when setting LOCATE_TARGET, and my understanding is that this is not exactly a good practice.

Directory Structure:

project/
    Jamfile
    src/
        main.c
    gen/
    bin/
        obj/

File Jamfile:

SubDir TOP ;

rule CreateHeader
{
    MakeLocate $(1) : $(LOCATE_SOURCE) ;
    Clean clean : $(1) ;
}

actions CreateHeader
{
    BUILD_DATE=`date`
    echo "char build_date[] = \"$BUILD_DATE\";" > $(1)
}

SEARCH_SOURCE = src ;
LOCATE_TARGET = bin/obj ;
SubDirHdrs gen ;
Object main.o : main.c ;

LOCATE_TARGET = bin ;
MainFromObjects app : main.o ;

LOCATE_SOURCE = gen ;
CreateHeader info.h ;

File src/main.c

src/main.c
#include <stdio.h>
#include "info.h"

int main(int argc, char *argv[])
{
    printf("Program built with Jam on %s.\n", build_date);

    return 0;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T11:53:40+00:00Added an answer on June 13, 2026 at 11:53 am

    Changing all #include directives to omit the path (i.e. ‘#include “a.h’ etc.) and changing the Jamfile to the following will solve your issues:

    SubDir TOP ;
    
    SEARCH_SOURCE += [ FDirName $(SUBDIR) src ] ;
    LOCATE_SOURCE = [ FDirName $(SUBDIR) src ] ;
    
    rule CreateHeader
    {
        MakeLocate $(1) : $(LOCATE_SOURCE) ;
        Clean clean : $(1) ;
    }
    
    actions CreateHeader
    {
        echo "int x = 10;" > $(1)
    }
    
    Object a.o : a.c ;
    Object b.o : b.c ;
    Object c.o : c.c ;
    
    CreateHeader a.h ;
    CreateHeader b.h ;
    CreateHeader c.h ;
    

    Here’re the details:

    • SubDir should always be invoked in a Jamfile. It sets up several helpful (and in some cases necessary) variables, including SUBDIR, SEARCH_SOURCE, and LOCATE_SOURCE which are used here.
    • Adding the “src” subdirectory to SEARCH_SOURCE allows you to omit the “src/” part for the source files in the Object rule invocations. SEARCH_SOURCE is also automatically added to the include directories, which is why the #include directories can be shortened.
    • LOCATE_SOURCE is the directory where generated source files (e.g. generated yacc sources and headers) are placed. For sake of consistency CreateHeader uses this variable. Note that this allows (and requires) you to omit the “src/” part in the CreateHeader invocations.

    So the general thrust of these changes is to omit the “src/” part from target names used in the Jamfile. It is generally recommended to omit directory components in Jamfiles (and use grist for disambiguation instead). It is important to note that the way Jam works targets with the names “src/a.h” and “a.h” are different targets, even if the former is considered to be located in “.” and the latter in “./src” (e.g. by means of the on-target SEARCH or LOCATE variables). With the files you gave Jam’s header scanning results in the following include dependencies (those are target names):

    src/a.c : src/a.h
    b.c     : src/b.h
    src/c.c : c.h
    

    This makes obvious why jamming “c.o” fails: The target “c.h” is unknown, since the target name of the header you declare to be generated is “src/c.h”. Hence jam ignores the include dependency. The reason for the failing “jam a.o” is the one you suspected.

    The change I suggest requires adjusting the #include directives in the source files, which may not be desirable/possible in your actual use case. The situation would still be salvageable. E.g. you can change the Jamfile as suggested, but extend the CreateHeader rule:

    rule CreateHeader
    {
        MakeLocate $(1) : $(LOCATE_SOURCE) ;
        Clean clean : $(1) ;
        Depends src/$(1) : $(1) ;
        NotFile src/$(1) ;
    }
    

    This is obviously a bit of a hack. It defines the targets “src/a.h” and friends as pseudo targets, each depending on the corresponding actual target (“a.h” etc.). This way Jam’s header scanning will result in a known target regardless of whether it has the “src/” prefix or not.

    The less hacky solution is to explicitly declare the include relations, though:

    Includes a.c : a.h ;
    Includes b.c : b.h ;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This is actually a problem that I've already solved, but I suspect that there
I suspect that I can't do this, but figured I'd ask the wise community
My company has a problem: we suspect that the NACHA files we are receiving
The name says it all really. I suspect that insertion sort is best, since
I suspect I am going to feel really stupid after posting this but here
I suspect that RegSetValueEx is thread safe, but would like some confirmation from the
I use numpy for numerical linear algebra. I suspect that I can get much
I suspect that I am missing something very obvious here but this doesn't work:
I suspect that this is going to sound like a stupid question, but, having
I suspect that this problem might be connected to my routing, or my view.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.