Makefile that distinguishes between Windows and Unix-like systems - linux

I would like to have the same Makefile for building on Linux and on Windows. I use the default GNU make on Linux and the mingw32-make (also GNU make) on Windows.
I want the Makefile to detect whether it operates on Windows or Linux.
For example make clean command on Windows looks like:
clean:
del $(DESTDIR_TARGET)
But on Linux:
clean:
rm $(DESTDIR_TARGET)
Also I would like to use different directory separator on Windows (\) and Linux (/).
It is possible to detect Windows operating system in Makefile?
PS: I do not want to emulate Linux on Windows (cygwin etc.)
There is similiar question: OS detecting makefile, but I didn't find the answer here.

I solved this by looking for an env variable that will only be set on windows.
ifdef OS
RM = del /Q
FixPath = $(subst /,\,$1)
else
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
endif
endif
clean:
$(RM) $(call FixPath,objs/*)
Because %OS% is the type of windows, it should be set on all Windows computers but not on Linux.
The blocks then setups up variables for the different programs as well as a function for converting the forward slashes into backslashes.
You to have to use $(call FixPath,path) when you call an outside command (internal commands work fine). You could also use something like:
/ := /
and then
objs$(/)*
if you like that format better.

The SystemRoot trick didn't work for me on Windows XP but this did:
ifeq ($(OS),Windows_NT)
#Windows stuff
...
else
#Linux stuff
....
endif

You should probably use the $(RM) variable to remove some files.

Checking WINDIR or COMSPEC is case-sensitive. Instead, I came up
with the following solution, hope that helps someone someday:
# detect if running under unix by finding 'rm' in $PATH :
ifeq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
WINMODE=1
else
WINMODE=0
endif
ifeq ($(WINMODE),1)
# native windows setup :
UNLINK = del $(subst /,\,$(1))
CAT = type $(subst /,\,$(1))
else
# cross-compile setup :
UNLINK = $(RM) $(1)
CAT = cat $(1)
endif

I would like to have the same Makefile for building on Linux and on Windows.
Maybe you will like CMake

Related

Automake conditional compilation from C or Objective-C sources

I'm using the following to do conditional compilation in automake of the amhello example program [1]:
In configure.ac:
AC_INIT([amhello], [1.0], [bug-automake#gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_PROG_OBJC
build_linux=no
build_windows=no
build_mac=no
AC_CANONICAL_HOST
case "${host_os}" in
cygwin*|mingw*)
build_windows=yes;;
darwin*)
build_mac=yes;;
*)
build_linux=yes;;
esac
AM_CONDITIONAL([LINUX], [test "$build_linux" = "yes"])
AM_CONDITIONAL([WINDOWS], [test "$build_windows" = "yes"])
AM_CONDITIONAL([MACOS], [test "$build_mac" = "yes"])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
AC_OUTPUT
In src/Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = main.c
if MACOS
hello_SOURCES += hello-mac.m
endif
if LINUX
hello_SOURCES += hello-linux.c
endif
It works as expected except for one issue - even when compiling on Linux, it tries to use the Objective-C build suite instead of the C one. A side effect of this is that OBJCFLAGS gets used instead of CFLAGS, which is counter-intuitive given that no Objective-C source code is being compiled when built for Linux. A demonstration:
$ OBJCFLAGS="-DOBJCFLAGS" CFLAGS="-DCFLAGS" ./configure
...
$ make
make all-recursive
make[1]: Entering directory '/'
Making all in src
make[2]: Entering directory '/src'
gcc -DHAVE_CONFIG_H -I. -I.. -DCFLAGS -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -I.. -DCFLAGS -MT hello-linux.o -MD -MP -MF .deps/hello-linux.Tpo -c -o hello-linux.o hello-linux.c
mv -f .deps/hello-linux.Tpo .deps/hello-linux.Po
gcc -DOBJCFLAGS -o hello main.o hello-linux.o
...
From the generated src/Makefile:
...
hello$(EXEEXT): $(hello_OBJECTS) $(hello_DEPENDENCIES) $(EXTRA_hello_DEPENDENCIES)
#rm -f hello$(EXEEXT)
$(AM_V_OBJCLD)$(OBJCLINK) $(hello_OBJECTS) $(hello_LDADD) $(LIBS)
...
Is there a good way to have the C compiler / CFLAGS be used when building for Linux and have the Objective-C compiler / OBJCFLAGS only be used when building for MacOS (when the Objective-C source file is to actually be built)? I tried using both approaches to conditional compilation described in [2] but both exhibit the same behavior.
[1] https://www.gnu.org/software/automake/manual/html_node/Creating-amhello.html#Creating-amhello
[2] https://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html#Conditional-Sources
I expect that if you tell automake to build different executables for Linux, Windows and MacOS instead of building the same executable with some OS specific variants, automake should not try an Objective-C compiler for the Linux and Windows versions as long as the Linux and Windows do not use any Objective-C sources.
NOTE: This is speculative, verification is needed.
Now... you will need to call these three executables three distinct names if you are going to define them in the same Makefile.am, or define them in multiple Makefile.am files. I can see a few possibilities to do that, and you may need to add subdir-objects to AM_INIT_AUTOMAKE([...]) and re-run autoreconf.
Note that I have not tested any of this, as I have no idea about how to write Objective-C code. If you happen to have your project available somewhere to look (with maybe a proof-of-concept hello-windows.c using winapi, and absolutely hello-macos.m using MacOS APIs), I can try to figure out which of the following proposals works best.
Use recursive make and src/linux/hello, src/windows/hello, src/macos/hello with one Makefile.am each, and move the OS-specific hello-$OS.* into the appropriate subdirectory:
# src/linux/Makefile.am
if LINUX
bin_PROGRAMS = hello
hello_SOURCES = hello-linux.c ../main.c
endif
# src/macos/Makefile.am
if MACOS
bin_PROGRAMS = hello
hello_SOURCES = hello-macos.m ../main.c
endif
# src/windows/Makefile.am
if WINDOWS
bin_PROGRAMS = hello
hello_SOURCES = hello-windows.c ../main.c
# special rules to build object from resource file and adding it
endif
I do not like source files beginning with ../, though. And the less recursive make we use, the better on multicore machines.
Use non-recursive make for the three executables built as src/linux/hello, src/windows/hello, src/macos/hello with one Makefile-files file each, all included from src/Makefile.am, moving the OS specific sources to the OS specific subdirectory:
# src/linux/Makefile-files -*- makefile-automake -*
if LINUX
bin_PROGRAMS += linux/hello
linux_hello_SOURCES = linux/hello-linux.c main.c
endif
# src/macos/Makefile-files -*- makefile-automake -*
if MACOS
bin_PROGRAMS += macos/hello
macos_hello_SOURCES = macos/hello-macos.m main.c
endif
# src/windows/Makefile-files -*- makefile-automake -*
if WINDOWS
bin_PROGRAMS += windows/hello
windows_hello_SOURCES = windows/hello-windows.c main.c
# special rules to build object from resource file and adding it
endif
# src/Makefile.am
bin_PROGRAMS =
include linux/Makefile-files
include macos/Makefile-files
include windows/Makefile-files
I would write the Makefile-files files using %reldir% and %canon_reldir% (or %D% and %C%).
This allows OS specific files and build rules (e.g. Windows resource files and the rules to compile them and link them to the Windows executable) to be all neatly put into the OS specific subdirectory.
Probably my preferred option for the longer term.
Just call the executables linux/hello, windows/hello, and macos/hello from src/Makefile.am without moving the sources or the build rules away from src/:
# src/Makefile.am
bin_PROGRAMS =
if LINUX
bin_PROGRAMS += linux/hello
linux_hello_SOURCES = hello-linux.c main.c
endif
if MACOS
bin_PROGRAMS += macos/hello
macos_hello_SOURCES = hello-macos.m main.c
endif
if WINDOWS
bin_PROGRAMS += windows/hello
windows_hello_SOURCES = hello-windows.c main.c
# special rules to build object from resource file and adding it
endif
If there is a lot of OS specific source files and rules all in the single directory src/ and its src/Makefile.am, this might become difficult to read.
My preferred option for a quick minimum working example.
Call the executables hello-linux, hello-windows, hello-macos from src/Makefile.am and then deal with installing the different executables as hello or hello.exe in install-hooks and the like.
I would avoid this as those hooks and related stuff are non-trivial to get right.
It still needs to be checked whether configure will actually succeed when building for Linux and Windows without an Objective-C compiler to be found.
The OBJCFLAGS are used only at link time, because automake selects the Objective-C linker if it sees any Objective-C source files. See this page in the automake manual.
You can use a per-target _LINK variable to override the default linker selection. In Makefile.am, you can write this, to force the use of the C linker:
hello_LINK = $(LINK)

How to setup makefile in windows

I tried to download cygwin to run my makefile but I get the following error:
> make
FIND: formato del parametro non corretto
FIND: formato del parametro non corretto
g++ -o esempio
g++.exe: fatal error: no input files
compilation terminated.
makefile:12: recipe for target 'esempio' failed
make: *** [esempio] Error 1
This is my basic makefile:
PHONY: all clean
CPPSOURCES += $(shell find . -name '*.cpp')
clean:
rm esempio
all: esempio
#true
esempio: $(CPPSOURCES)
g++ $(CPPSOURCES) -o esempio
what can I do to fix it?
Two things look unusual to me. First is this:
CPPSOURCES += $(shell find . -name '*.cpp')
You usually use wildcard instead of find. I would change it to the following:
CPPSOURCES = $(sort $(wildcard *.cpp))
CPPOBJECTS = $(CPPSOURCES:.cpp=.o)
Second, for your esempio recipe, use CPPOBJECTS instead of CPPSOURCES:
esempio: $(CPPOBJECTS)
$(CXX) $(CXXFLAGS) $(CPPOBJECTS) -o esempio
The use of true in one recipe also looks kind of odd (but it appears to work). You could change it to the following and move it to the top of the file so it is the default recipe:
.PHONY: all
all esempio: $(CPPOBJECTS)
$(CXX) $(CXXFLAGS) $(CPPOBJECTS) -o esempio
Here is an example of a makefile that uses a lot of GNU extra features.
You have the dos command directory ahead of the cygwin bin directory in the PATH.
This is my cygwin path:
$ echo $PATH
$HOME/bin:/usr/local/bin:/usr/bin:/cygdrive/c/Go/bin:/bin
The only windows directory is the golang bin directory. Use cygpath the find the cygwin equivalent directory name.
The simplest way to do this is to remove all windows directories and only add back the few you need. To do this, modify your user environment variables to add CYGWIN_NOWINPATH=1. In your .bashrc you can add back the cygwin equivalent for only those windows directories that you find you really need.

Makefile rule is not executing in Linux

I am trying to build the Atmel BitCloud v3.2 sample application Blink with the makefile in Linux and Mac. Everything works fine in Windows. But in Posix-like systems the following lines are not working:
all: directories images root_files size
$(OBJ_PATH)/%.o: $(SRCS)
$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $#)), $(SRCS)) -o $#
Therefore, the compiler is not being executed and object files are not being created. As the result the linker displays error messages such as
avr-gcc: error: All_MegaRf_Atmega256rfr2_8Mhz_Gcc/Obj/blink.o: No such file or directory
The line $(OBJ_PATH)/%.o: $(SRCS) is the source of the problem.
If I substitute it with smth like $(OBJ_PATH)/blink.o: ../../src/blink.c the corresponding object-file is being successfully created.
I was even able to build the whole application by manually setting build targets as follows:
$(OBJ_PATH)/blink.o: ../../src/blink.c
$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $#)), $(SRCS)) -o $#
$(OBJ_PATH)/stdPdsEvents.o: ../../../../BitCloud/Components/PersistDataServer/std/src/stdPdsEvents.c
$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $#)), $(SRCS)) -o $#
for all the .c files in the project.
The list of sources on the other hand is defined like this:
SRCS = \
../../src/blink.c \
../../../../BitCloud/Components/PersistDataServer/std/src/stdPdsMemAccess.c \
../../../../BitCloud/Components/PersistDataServer/std/src/stdPdsTimer.c \
Can anyone help me to figure out why is the pattern matching not working and how to recover it.
Note: Similar topic has already been open here, but the solution found by th author himself wasn't explained well in my opinion, so I couldn't solve my problem.
The construct to have each object file depend on all source files and then have the compilation step fish the actually useful file out of the list of sources is quite dubious. A better approach would be to generate a Makefile snippet and include it, something like this:
makefile.d:
echo "$(SRCS)" \
| tr ' ' '\n' \
| sed -n 's%\(.*\)/\([^/]*\)\.c$$%$(OBJ_PATH)/\2.o: \1/\2.c%p' >$#
include makefile.d
All details of sed are not properly standardized, so you may be better off rewriting the substitution in Perl or something. The beef here is how we capture the path and the base name and generate a specific rule for each dependency.
Managed to solve it finally.
In order to make it compile both in Windows and Linux one should change the makefile as shown below:
objects := $(patsubst %.c,$(OBJ_PATH)/%.o,$(notdir $(SRCS)))
$(objects): $(SRCS)
#$(OBJ_PATH)/%.o: $(SRCS)
$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $#)), $(SRCS)) -o $#
where $(OBJ_PATH)/%.o: $(SRCS) shall be commented or removed.
After having done this way the project can be built under linux or mac and under windows both in Atmel Studio 6.2 and Atmel Studio 7. The latter was not able to build just like it was not possible in linux or mac.

Make could not see commands (recipes) except gcc

My system is windows 8.1. I'm working on cygwin 32 bit version (first i set up 64 bit version and could not uninstall completely , later set up 32 bit version).I simply want to use 'make' utility. All my makefiles' extensions are 'makefile'.
When i try this below (to see them work , I only use simple makefiles)
make kernel.o (in shell)
kernel.o : kernel.c
<tab>gcc - ffreestanding -c $< -o $#
it works , and compiles.
But these ones below do not work. And for testing purposes and keeping things simple, each source and corresponding makefiles are in own directory. And all make commands've been made in the current directory where source and corresponding makefiles are located.
All executables (nasm ,ld ,objcopy ,cat) that cygwin needs to run the recipes are in the same directory (that is c:\cygwin\bin\)
If i command the recipes from shell, they work.
I also changed source files to see what would happen.
I also thought that maybe the problem is from cygwin itself , and i set up linux ubuntu desktop version to my machine. But they are (recipes below) not working too.(and also If i command the recipes from shell, they work.)
make kernel_entry.o (in shell)
make: *** No rule to make target 'kernel_entry.o'.
Rule:
kernel_entry.o : kernel_entry.asm
<tab>nasm $< -o $# -f coff (coff for windows)
//--------------------------------
make os-image.bin (in shell)
make: *** No rule to make target 'os-image.bin'.
Rule:
os-image.bin: boot.bin kernel.bin
<tab>cat $< > $#
//--------------------------------
make boot.bin
make: *** No rule to make target 'boot.bin'.
Rule :
boot.bin : boot.asm
<tab> nasm $< -f bin -o $#
*recipes with ld and objcopy also does not work.*
Thank you in advance...
These are my files and directory appearance :
C:\cygwin\bin --> where gcc.stays
C:\cygwin\bin --> where make.exe stays
C:\cygwin\bin --> where objcopy stays
C:\cygwin\bin --> where nasm.exe stays
C:\cygwin\bin --> where ld stays
C:\cygwin\home\me\OS\boot --> where boot.makefile stays and also boot.asm source code
C:\cygwin\home\me\OS\kernel --> where kern.makefile stays ( working sample ) and also kernel.c source code
And this is cygwin shell appearance:
me#Me ~/os/kernel
$ dir
kern.makefile kernel.c kernel_entry.asm
**in my kern.makefile the existing rule is as follows
kernel_entry.o : kernel_entry.asm
nasm $< -o $# -f coff
and boot directory
me#Me ~/os/boot
$ dir
boot.asm disk_load.asm print_hex.asm print_string_pm.asm
boot.makefile gdt.asm print_string.asm switch_to_pm.asm
**in my boot.makefile the existing rule is as follows
boot.bin : boot.asm
nasm $< -f bin -o $#
Make does not see your makefiles.
From the GNU make manual:
If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that order.
From what I see, your makefiles (kern.makefile, boot.makefile) are simply not found by your call to make (which does not have a -f option). This makes make rely on its internal rules, which do not include any %.o: %.asm dependency or somesuch (for make, assembly ends in .s, assembly with preprocessing to be done in .S).
This can become bloody confusing when your *.c and *.S files are compiled into *.o files, because make does have internal rules for those -- which, of course, stubbornly refuse to take any compiler options into account that you might have defined in that makefile of yours that make doesn't actually read. ;-)
So either call
make -f kern.makefile kernel.o
or (and this is my recommendation), rename <whatever>.makefile to Makefile (which is the canonical way of naming those).

Kernel module not building .ko file

I have a 3rd party device driver which I am trying to cross-compile. When I build the driver everything goes smooth but I don't see any driver.ko file, however driver.o file is generated fine and I don't see any error during the build process. I have also tried with the option V=1 and I see following error
echo;
echo " ERROR: Kernel configuration is invalid.";
echo " include/generated/autoconf.h or include/config/auto.conf are missing.";
echo " Run 'make oldconfig && make prepare' on kernel src to fix it.";
echo;
But my kernel configuration is correct and I have tried a simple hello world module with this configuration, in that case I can build my module but still see this error message. Also I can see both the files include/generated/autoconf.h & include/config/auto.conf in the kernel sources. Still why I am unable to build my driver module.
Here is the output of the build.
LD [M] /home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553/imx6build/host/os/linux/ar6000.o
Building modules, stage 2.
MODPOST 0 modules
make[2]: Leaving directory `/home/farshad/Work/CSP/projects/phase_1/farshad/cspbox/platform/imx6/mel5/fs/workspace/linux-2.6.38-imx6'
As you can see above ar6000.o is built properly without any error, but why ar6000.ko is not being built otherwise it should report "MODPOST 1 modules".
Since ar6000.ko is not being built at the end of the complete build process I also get the following error
cp: cannot stat `/home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553/imx6build/host/os/linux/ar6000.ko': No such file or directory
2404 make[1]: *** [install] Error 1
Which is obvious. My problem is why I am not getting a ar6000.ko in the first place. Searching over google someone also faced this issue and mentioned that running make with sudo resolved it but it brought no luck for me!
I am wandering is there any problem in my kernel configuration (i.e the driver is looking for some configuration setting which I haven't enabled in my kernel, but in that case it should give compiler error looking for required #define), the other point can be that there is a problem with the driver build system, which I am trying to figure out. My cross-compile environment is good as I am seeing exactly the same issue while building the same driver for my (Ubuntu x86) machine !!
Any thoughts.
Regards, Farrukh Arshad
UPDATE # 1
Its a 3rd party driver package which also build other utilities along with the driver module. Here is the output of the driver module build process
make CT_BUILD_TYPE=MX6Q_ARM CT_OS_TYPE=linux CT_OS_SUB_TYPE= CT_LINUXPATH=~/Work/CSP/projects/phase_1/farshad/cspbox/platform/imx6/mel5/fs/workspace/linu x-2.6.38-imx6 CT_BUILD_TYPE=MX6Q_ARM CT_CROSS_COM PILE_TYPE=~/bin/mgc/CodeSourcery/Sourcery_CodeBench_for_ARM_GNU_Linux/bin/arm-none-linux- gnueabi- CT_ARCH_CPU_TYPE=arm CT_HC_DRIVERS=pci_std/ CT_MAKE_INCLUDE_OVERRIDE= CT_BUILD_OUTPUT_OVERRIDE=/home/far shad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553 /imx6build/host/.output/MX6Q_ARM-SDIO/image -C /home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux _release_[posted_2011_8_19_olca3.1RC_553/imx6build/host/sdiostack/src default
make[3]: Entering directory `/home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olc a3.1RC_553/imx6build/host/sdiostack/src'
make -C ~/Work/CSP/projects/phase_1/farshad/cspbox/platform/imx6/mel5/fs/workspace/linux-2.6.38-imx6 SUBDIRS=/home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca 3.1RC_553/imx6build/host/sdiostack/src ARCH=arm CROSS_COMPILE=~/bin/mgc/CodeSourcery/Sourcery_CodeBench_for_ARM_GNU_Linux/bin/arm-none-linux-gnueabi- EXTRA_CFLAGS="-DLINUX -I/home/farshad/Work/CSP/board s/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553/imx6build/host/sdiostack/src/include -DDEBUG" modules
make[4]: Entering directory `/home/farshad/Work/CSP/projects/phase_1/farshad/cspbox/platform/imx6/mel5/fs/workspace/linux-2.6.38-imx6'
Building modules, stage 2.
MODPOST 0 modules
make[4]: Leaving directory `/home/farshad/Work/CSP/projects/phase_1/farshad/cspbox/platform/imx6/mel5/fs/workspace/linu x-2.6.38-imx6'
Here is the Makefile of the driver module.
ifdef CT_MAKE_INCLUDE_OVERRIDE
-include $(CT_MAKE_INCLUDE_OVERRIDE)
else
-include localmake.$(CT_OS_TYPE).inc
-include localmake.$(CT_OS_TYPE).private.inc
endif
export CT_OS_TYPE
export CT_OS_SUB_TYPE
export CT_OS_TOP_LEVEL_RULE
export CT_PASS_CFLAGS
export CT_SRC_BASE
export CT_BUILD_SUB_PROJ
# this makefile can only be invoked from the /EMSDIO/src base
CT_SRC_BASE :=$(shell pwd)
# export flags for which HCDs to build. Set the hcd driver name in hcd/ in your localmake.*.inc file.
export CT_HC_DRIVERS
export PDK_BUILD
export HDK_BUILD
export ALL_BUILD
export ATHRAW_FD_BUILD
export BUS_BUILD
# For Linux
ifeq ($(CT_OS_TYPE),linux)
#make a copy for linux 2.4
EXTRA_CFLAGS += -DLINUX -I$(CT_SRC_BASE)/include
ifneq ($(CT_RELEASE),1)
EXTRA_CFLAGS += -DDEBUG
endif
export EXTRA_CFLAGS
CT_SRC_OUTPUT :=$(CT_SRC_BASE)/../output
ifdef CT_BUILD_OUTPUT_OVERRIDE
_CT_COMPILED_OBJECTS_PATH :=$(CT_BUILD_OUTPUT_OVERRIDE)
_MAKE_OUTPUT_DIR :=
_CLEAN_OUTPUT_DIR :=
else
_CT_COMPILED_OBJECTS_PATH := $(CT_SRC_OUTPUT)/$(CT_BUILD_TYPE)
_MAKE_OUTPUT_DIR := mkdir --parents $(_CT_COMPILED_OBJECTS_PATH)
_CLEAN_OUTPUT_DIR := rm -R -f $(CT_SRC_OUTPUT)
endif
ifeq ($(CT_OS_SUB_TYPE),linux_2_4)
CT_PASS_CFLAGS := $(EXTRA_CFLAGS)
_CT_MOD_EXTENSION :=o
ifeq ($(ALL_BUILD),1)
subdir-m += busdriver/ lib/ hcd/ function/
else
ifeq ($(BUS_BUILD),1)
subdir-m += busdriver/ lib/ hcd/
else
ifeq ($(PDK_BUILD),1)
subdir-m += function/
else
ifeq ($(HDK_BUILD),1)
subdir-m += hcd/ function/
endif
endif
endif
endif
# add in rules to make modules
CT_OS_TOP_LEVEL_RULE :=$(CT_LINUXPATH)/Rules.make
include $(CT_OS_TOP_LEVEL_RULE)
else
#2.6+
_CT_MOD_EXTENSION :=ko
ifeq ($(ALL_BUILD),1)
obj-m += busdriver/ lib/ hcd/ function/
else
ifeq ($(BUS_BUILD),1)
obj-m += busdriver/ lib/ hcd/
else
ifeq ($(PDK_BUILD),1)
obj-m += function/
else
ifeq ($(HDK_BUILD),1)
obj-m += hcd/ function/
endif
endif
endif
endif
endif
ifdef CT_BUILD_SUB_PROJ
_CT_SUBDIRS=$(CT_BUILD_SUB_PROJ)
else
_CT_SUBDIRS=$(CT_SRC_BASE)
endif
ifdef CT_CROSS_COMPILE_TYPE
CT_MAKE_COMMAND_LINE=$(CT_OUTPUT_FLAGS) -C $(CT_LINUXPATH) SUBDIRS=$(_CT_SUBDIRS) ARCH=$(CT_ARCH_CPU_TYPE) CROSS_COMPILE=$(CT_CROSS_COMPILE_TYPE)
else
CT_MAKE_COMMAND_LINE=$(CT_OUTPUT_FLAGS) -C $(CT_LINUXPATH) SUBDIRS=$(_CT_SUBDIRS)
endif
makeoutputdirs:
$(_MAKE_OUTPUT_DIR)
default: makeoutputdirs
echo " ************ BUILDING MODULE ************** "
$(MAKE) $(CT_MAKE_COMMAND_LINE) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" modules
echo " *** MODULE EXTENSION = $(_CT_MOD_EXTENSION)"
$(CT_SRC_BASE)/../scripts/getobjects.scr $(CT_SRC_BASE) $(_CT_COMPILED_OBJECTS_PATH) $(_CT_MOD_EXTENSION)
ifeq ($(CT_OS_SUB_TYPE),linux_2_4)
# on 2.4 we can't invoke the linux clean with SUBDIRS, it will just clean out the kernel
clean:
find $(_CT_SUBDIRS) \( -name '*.[oas]' -o -name core -o -name '.*.flags' -o -name '.ko' -o -name '.*.cmd' \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
$(_CLEAN_OUTPUT_DIR)
else
clean:
$(MAKE) $(CT_MAKE_COMMAND_LINE) clean
find $(_CT_SUBDIRS) \( -name '*.[oas]' -o -name core -o -name '.*.flags' \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
$(_CLEAN_OUTPUT_DIR)
endif
endif
# For QNX
ifeq ($(CT_OS_TYPE),qnx)
LIST=VARIANT
EARLY_DIRS=lib
##ifndef QRECURSE
QRECURSE=./recurse.mk
##ifdef QCONFIG
###QRDIR=$(dir $(QCONFIG))
##endif
##endif
include $(QRDIR)$(QRECURSE)
endif
Ok, I have figured out the problem. I am having square bracket character "[" in the module source directory
LD [M] /home/farshad/Work/CSP/boards/imx6q/ar6k3/ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553/imx6build/host/os/linux/ar6000.o
Removing this from the path worked well and I got my kernel module object files. I have renamed
ar6003_3.1_RC_Linux_release_[posted_2011_8_19_olca3.1RC_553
to
ar6003,
and also tested with
ar6003_3.1_RC_Linux_release_posted_2011_8_19_olca3.1RC_553
Both worked fine. I was building on Ubuntu 10.04. A colleague of mine has built from the same sources having "[" character in his path on Ubuntu 11.04 and kernel module object file was building nicely, this also suggest the changed behavior of grep / find / awk or such utility among their different versions, which kernel build system is using, resulting in this issue.
Regards,
Farrukh Arshad.

Resources