Invoking cl.exe on a source file in a subdirectory

Say I have a source file:

Foo\Foo.cpp

And my nmake-based Makefile is as so:

.SUFFIXES: .cpp

.cpp.obj:
$(CL) $(CFLAGS) $**

SOURCES = \
Foo\Foo.cpp

OBJECTS = $(SOURCES:.cpp=.obj)

This establishes Foo\Foo.cpp => Foo\Foo.obj, which is what I want.

However when I invoke cl.exe on “Foo\Foo.cpp”, “Foo.obj” gets created in the current directory, not in Foo. So then nmake can’t find it.

I tried using “/Fo$@” as an option to cl.exe but this netted me the following error:

“NMAKE : fatal error U1100: macro ‘$@’ is illegal in the context of batch rule ‘.c.obj’”

???

All I want is for Foo.obj to be created in Foo, or some other sane way to compile source files in subdirectories (and ideally not end up with a ton of .obj files in CWD). I know I’ve gotta be overlooking something.

Hello, Mr.Aseltine,
the following nmake-file looks like making the trick:



SRC_DIR = foo
OBJ_DIR = _obj

.SUFFIXES : .cpp .obj

{$(SRC_DIR)}.cpp{$(OBJ_DIR)}.obj :
$(CC) $(CFLAGS) /c $< -Fo$@

OBJECTS = <br> $(OBJ_DIR)\foo.obj <br> $(OBJ_DIR)\foo2.obj

make_objects : $(OBJECTS)

the directory layout is supposed to look like this:

./makefile
./foo/foo.cpp
./foo/foo2.cpp
./_obj

‘nmake.exe’ is to be started at ‘./’
Objects are put into the
./_obj/foo.obj
./_obj/foo2.obj

kt133a wrote:

Hello, Mr.Aseltine, the following nmake-file looks like
making the trick:

SRC_DIR = foo
OBJ_DIR = _obj

Okay, maybe it wasn’t clear, but it’s not like all my source files are in Foo/. It’s more like:

Foo1/Foo1.cpp
Foo2/Foo2.cpp
Foo3/Foo3.cpp

So I don’t think a singular “SRC_DIR” is going to work?

Chris,

Okay, maybe it wasn’t clear, but it’s not like all my source files are in Foo/.

It’s more like:

Foo1/Foo1.cpp
Foo2/Foo2.cpp
Foo3/Foo3.cpp

And what is Windows nmake like? Is it basically different from gmake, pmake and/or any other makefile that may only exist under UNIX-like system? The most obvious approach to your problem under UNIX-like system is to write a corresponding makefile for every subdirectory that you want to be included in the build, and to reference them in top-level makefile. For example, assuming that you use gmake and that /home/chris/Foo is your top-level directory while Foo1, Foo2 and Foo3 are its subdirectories, you could put the following lines in /home/chris/Foo/Makefile

SUBDIRS = Foo1 Foo2 Foo3

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):
$(MAKE) -C $@

If you do it this way, Make is going to check every subdirectory that is mentioned in top-level makefile for the presence of its corresponding makefile, and process it if its is found. The same applies to child makefiles in subdirectories of Foo1,Foo2 and Foo3 that may, in turn, have their
subdirectories with ther corresponding child makefiles, and so on and so forth. As you can see, this apporach allows incredible flexibiliy - your rules may be different for every subdirectory.

Can’t you do the same with nmake under Windows? OTOH, IIRC, Windows has quite a few “specifics”. For example, IIRC, you are not supposed to edit a pre-defined Makefile that comes with WDK - instead, you edit only sources file…

Anton Bassov

anton bassov wrote:

And what is Windows nmake like? Is it basically different
from gmake, pmake and/or any other makefile that may
only exist under UNIX-like system?

Well, it must be, because I build this same codebase on Linux and I simply tell it:

SRCS = Foo1\Foo1.cpp Foo2\Foo2.cpp {etc.}

OBJS = $(patsubst %.cpp,%.o,$(SRCS))

$(OBJS): %.o: %.cpp
@echo Compiling $<
@$(CXX) -c $(CFLAGS) $< -o $@

And I get Foo1\Foo1.o, Foo2\Foo2.o, and so on.

All the source files are conceptually part of one big static library. There are probably 30 subfolders at least, I wouldn’t want to write 30 Makefiles for each subfolder.

> Well, it must be, because I build this same codebase on Linux and I simply tell it:

SRCS = Foo1\Foo1.cpp Foo2\Foo2.cpp {etc.}

Well, you seem to be a true masochist then…

There are probably 30 subfolders at least, I wouldn’t want to write 30 Makefiles for each subfolder.

Well, I would rather write 30 makefiles - although it seems, at the first glance, to involve quite a bit of work, don’t forget that the whole process of writing simplistic makefiles can be automated with a simple script (ls command seems to be your most obvious friend here)…

Anton Bassov

On Mar 10, 2015, at 6:07 PM, xxxxx@gmail.com wrote:

kt133a wrote:

> Hello, Mr.Aseltine, the following nmake-file looks like
> making the trick:
>
> SRC_DIR = foo
> OBJ_DIR = _obj

Okay, maybe it wasn’t clear, but it’s not like all my source files are in Foo/. It’s more like:

Foo1/Foo1.cpp
Foo2/Foo2.cpp
Foo3/Foo3.cpp

So I don’t think a singular “SRC_DIR” is going to work?

The problem is not nmake. The problem is “build”. It simply doesn’t support this. The design model is that each directory produces a binary, like a library, and then the final step combines those library with some other source files to produce an executable.

If that’s not flexible enough, here is your incentive to finally dump the Windows 7 WDK and move to the Windows 8 WDK, where you get the full power of Visual Studio project files.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

On Wed, Mar 11, 2015 at 11:49 AM, Tim Roberts wrote:

> On Mar 10, 2015, at 6:07 PM, xxxxx@gmail.com wrote:
> >
> > kt133a wrote:
> >
> >> Hello, Mr.Aseltine, the following nmake-file looks like
> >> making the trick:
> >>
> >> SRC_DIR = foo
> >> OBJ_DIR = _obj
> >
> > Okay, maybe it wasn’t clear, but it’s not like all my source files are
> in Foo/. It’s more like:
> >
> > Foo1/Foo1.cpp
> > Foo2/Foo2.cpp
> > Foo3/Foo3.cpp
> >
> > So I don’t think a singular “SRC_DIR” is going to work?
>
> The problem is not nmake. The problem is “build”. It simply doesn’t
> support this. The design model is that each directory produces a binary,
> like a library, and then the final step combines those library with some
> other source files to produce an executable.
>
> If that’s not flexible enough, here is your incentive to finally dump the
> Windows 7 WDK and move to the Windows 8 WDK, where you get the full power
> of Visual Studio project files.
> —
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
>
May not be directly helpful to solve your problem, CMake (
http://www.cmake.org/) is another flexible cross platform build system. It
can generate project files (visual studio, eclipse, unix makefile…) from
a simple “cmake” file

> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Chris Aseltine wrote:

Okay, maybe it wasn’t clear, but it’s not like all my
source files are in Foo/. It’s more like:

Foo1/Foo1.cpp
Foo2/Foo2.cpp
Foo3/Foo3.cpp

So I don’t think a singular “SRC_DIR” is going to work?

Well, an extensive approach works anyway:



SRC_DIR1 = foo
SRC_DIR2 = bar
OBJ_DIR1 = obj$(SRC_DIR1)
OBJ_DIR2 = obj$(SRC_DIR2)

.SUFFIXES : .cpp .obj

{$(SRC_DIR1)}.cpp{$(OBJ_DIR1)}.obj :
$(CC) $(CFLAGS) /c $< -Fo$@

{$(SRC_DIR2)}.cpp{$(OBJ_DIR2)}.obj :
$(CC) $(CFLAGS) /c $< -Fo$@

OBJECTS = <br> $(OBJ_DIR1)\foo.obj <br> $(OBJ_DIR1)\foo2.obj <br> $(OBJ_DIR2)\bar.obj <br> $(OBJ_DIR2)\bar2.obj

make_objects : $(OBJECTS)

But as now given there could be dozens (or let’s take thousands) of src/obj directories in your project then in my opinion the raw nmake or even a whole WinSDK/WDK build-nmake system are just unsuitable for your purposes. Since these tools are too specific in a way they maintain the directory structure of a project.

Well, it must be, because I build this same
codebase on Linux and I simply tell it

Nmake is far less by its capabilities compared with gnumake, so it’s typically impossible to adopt gnu-makefiles to work with nmake.

The % things are so called pattern rules, nmake does not support it.
Anyway - build or msbuild - no WDK works with gmake.
Windows is not Linux…

Maybe you’re going to generate a msbuild project, manually or with
something like cmake.

– pa

On 11-Mar-2015 07:30, xxxxx@gmail.com wrote:

I build this same codebase on Linux and I simply tell it:

SRCS = Foo1\Foo1.cpp Foo2\Foo2.cpp {etc.}

OBJS = $(patsubst %.cpp,%.o,$(SRCS))

$(OBJS): %.o: %.cpp
@echo Compiling $<
@$(CXX) -c $(CFLAGS) $< -o $@

And I get Foo1\Foo1.o, Foo2\Foo2.o, and so on.

All the source files are conceptually part of one big static library. There are probably 30 subfolders at least, I wouldn’t want to write 30 Makefiles for each subfolder.

anton bassov wrote:

> Well, it must be, because I build this same codebase on
> Linux and I simply tell it:
>
> SRCS = Foo1\Foo1.cpp Foo2\Foo2.cpp {etc.}

Well, you seem to be a true masochist then…

Wait, what about this is masochistic? Having source files in different subdirectories is masochistic??

I mean, I feel like the answer I’m getting here is “you just can’t do that”, at least with nmake so I guess maybe I have to find something else (as others suggested).

xxxxx@gmail.com wrote:

Wait, what about this is masochistic? Having source files in different subdirectories is masochistic??

I mean, I feel like the answer I’m getting here is “you just can’t do that”, at least with nmake so I guess maybe I have to find something else (as others suggested).

If you are using a “build”-based WDK (meaning 7600 or earlier), then the
answer absolutely is “you just can’t do that”. It is a fundamental
limitation of “build”. Always has been. If you’ve ever seen the
build process for a Windows CE system, where you build the entire
operating system, you see that there are a bazillion subdirectories,
each of which has its own “sources” file and produces a single static
library. When it’s time to build DLLs and executables, you have a few
source files linking with dozens of static libraries.

That’s just the way “build” was designed.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts wrote:

If you are using a “build”-based WDK (meaning 7600 or earlier), then
the answer absolutely is “you just can’t do that”. It is a fundamental
limitation of “build”.

Okay, I can live with that. But is Anton right? I’m a sadomasochist for having my sources in more than one subdirectory? Like, whips, chains, everything?

You can do it with nmake, build + nmake is something else. The simplest way
to get what you want is to have “decoy” source files that #include the
subdir source files.

foo1.cpp:
#include “Foo1\Foo1.cpp”

Your Foo dirs can now be anywhere.
But I suspect you aren’t going to like that option either.

Mark Roddy

On Wed, Mar 11, 2015 at 2:26 PM, wrote:

> anton bassov wrote:
>
> >> Well, it must be, because I build this same codebase on
> >> Linux and I simply tell it:
> >>
> >> SRCS = Foo1\Foo1.cpp Foo2\Foo2.cpp {etc.}
> >
> > Well, you seem to be a true masochist then…
>
> Wait, what about this is masochistic? Having source files in different
> subdirectories is masochistic??
>
> I mean, I feel like the answer I’m getting here is “you just can’t do
> that”, at least with nmake so I guess maybe I have to find something else
> (as others suggested).
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

xxxxx@gmail.com wrote:

Tim Roberts wrote:
> If you are using a “build”-based WDK (meaning 7600 or earlier), then
> the answer absolutely is “you just can’t do that”. It is a fundamental
> limitation of “build”.
Okay, I can live with that. But is Anton right? I’m a sadomasochist for having my sources in more than one subdirectory? Like, whips, chains, everything?

That’s a philosophical issue. There is a certain amount of sense to the
philosophy that each subdirectory should produce one build product. I
have a tendency to manage this kind of thing by creating virtual folders
in my Visual Studio project, leaving the files in one physical
directory, although Visual Studio doesn’t have any problem pulling the
files from different physical directories.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I interpreted Anton’s comment within the context of do this with the old
BUILD system. This type of file structure without a bunch of libraries
is fundamentally incompatible with the BUILD system and trying to fight
with it is going to be painful.

If the idea of that appeals to you, then, yes, you are a masochist. If
you’re going to tell someone else they have to do it, then you’re the
sadist. :stuck_out_tongue:

On 3/11/2015 12:15 PM, xxxxx@gmail.com wrote:

Tim Roberts wrote:

> If you are using a “build”-based WDK (meaning 7600 or earlier), then
> the answer absolutely is “you just can’t do that”. It is a fundamental
> limitation of “build”.
Okay, I can live with that. But is Anton right? I’m a sadomasochist for having my sources in more than one subdirectory? Like, whips, chains, everything?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> Wait, what about this is masochistic? Having source files in different subdirectories

is masochistic??

Having files in different subdirectories is not masochistic at all. However, manually mentioning them one after another in a single makefile seems to be, indeed, masochistic - if you have at least 30 directories you,apparently probably have HUNDREDS (if not thousands) of files. Once you said that were/are doing it under Linux, why don’t you want to write a script that generates a simplistic makefile for every target directory???

Anton Bassov

> Anyway - build or msbuild - no WDK works with gmake.

Is it possible to add the pre-build custom build step to BUILD to copy all files to the same dir?

I know (and use a lot) the post-build steps. What about pre-build?

Maxim S. Shatskih

Microsoft MVP on File System And Storage

xxxxx@storagecraft.com

http://www.storagecraft.com

>cross platform build system. It can generate project files (visual studio, eclipse, unix makefile…) from

a simple “cmake” file

If old (pre-MSBuild) WDK is a requirement, then the best you can do with CMake is to a) copy all files to same dir using configure_file() operator b) generate the SOURCES file off CMake c) invoke DDKBUILD.BAT from CMake.

Don’t know about modern MSBuild-based WDK. Probably CMake already has a generator for MSBuild.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

On 11-Mar-2015 21:15, xxxxx@gmail.com wrote:

But is Anton right? I’m a sadomasochist for having my sources in more than one subdirectory? Like, whips, chains, everything?

… threat of a lawsuit and going to hell :wink:

This project simply was not “Designed For Windows”.
(remember, not so long ago even hardware used to be “Designed For Windows”?)
This is simply yet another case of “Windows is not Linux”.
If the layout of source tree were planned with WDK in mind, it weren’t a
problem at all.

If you don’t want each subdir be a library, you can do as Mark R.
advised - gather all files into one directory using stub C files or
symbolic links. Or generate a vcproj for msbuild-based WDKs.

/* OS X is not Linux too, but Apple can afford being different :slight_smile: */

– pa