I have a makefile which builds a project composed of many files which all need to be built.
To make matters more complicated, I have a number of included directories in each call to gcc (so each call to gcc looks long on the command line).
I'd like to suppress all output except for errors and warnings (so that I can actually see them when make runs!)
Is there any way to do this?
make -s should do what you're after a bit more neatly. I don't know of a way to force it on the makefiles, but the GNU manual might have one.
Failing that you could check the Linux kernel build system, since that seems to automatically hide stdout.
By adding a "#" to the front of a command, the command line string is suppressed
e.g.
from
$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
to
$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c
#$(CC) -c $(CFLAGS) $< -o $#
will take
make[1]: Entering directory `.../libraries/libgcdc/build'
/home/crowe/arm-tools/gcc-arm-none-eabi-4_6-2012q2/bin/arm-none-eabi-gcc -c -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Werror-implicit-function-declaration -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code -Wcast-align --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -g -O0 -D DEBUG -I.. -I../include -I../../libchip_sam3s -I../../libboard_arm_demo -I../../libboard_generic -I../../libusb/include -Dsam3s4 -DTRACE_LEVEL=5 -Dprintf=iprintf ../source/hid_callbacks.c -o debug_sam3s_svn2/hid_callbacks.o
make[1]: Leaving directory ` .../libraries/libgcdc/build'
to
make[1]: Entering directory `.../libraries/libgcdc/build'
make[1]: Leaving directory `.../libraries/libgcdc/build'
You can also force the -s option as suggested by PaulW directly in the Makefile. Just add:
.SILENT:
Depending on how "errors and warnings" are reported ...
make > /dev/null
That will redirect all STDOUT (Standard Output) from the make command (and thus all sub-processes it spawns) to the endless bit-bucket of nothingness. This may be too greedy though, as some programs use STDOUT (and not STDERR) to report warnings.
I do not know of a way globally change STDOUT of all sub-processes from within the context of the Makefile itself.
Happy coding.
Related
I'm trying to install mxnet by cloning a git repository as follows:
git clone --recursive https://github.com/dmlc/mxnet
However, when I try to build it by dropping into the mxnet directory and running make as follows:
make -j $(nproc) USE_OPENCV=1 USE_BLAS=openblas USE_CUDA=1 USE_CUDA_PATH=/usr/local/cuda USE_CUDNN=1
I get errors indicating that cblas.h cannot be found - e.g.
/home/me/mxnet/3rdparty/mshadow/mshadow/./base.h:162:14: fatal error: cblas.h: No such file or directory
#include <cblas.h>
The output of make is a series of nvcc compilation commands that seem to be as follows:
/usr/local/cuda/bin/nvcc -std=c++11 -Xcompiler -D_FORCE_INLINES -O3 -ccbin /home/me/anaconda2/envs/deepnets/bin/x86_64-conda_cos6-linux-gnu-c++ -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -gencode arch=compute_50,code=sm_50 -gencode arch=compute_52,code=sm_52 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_61,code=sm_61 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=[sm_75,compute_75] --fatbin-options -compress-all -Xcompiler "-DMSHADOW_FORCE_STREAM -Wall -Wsign-compare -O3 -DNDEBUG=1 -I/home/me/mxnet/3rdparty/mshadow/ -I/home/me/mxnet/3rdparty/dmlc-core/include -fPIC -I/home/me/mxnet/3rdparty/tvm/nnvm/include -I/home/me/mxnet/3rdparty/dlpack/include -I/home/me/mxnet/3rdparty/tvm/include -Iinclude -funroll-loops -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedefs -msse3 -mf16c -I/usr/local/cuda/include -DMSHADOW_USE_CBLAS=1 -DMSHADOW_USE_MKL=0 -I/home/me/mxnet/3rdparty/mkldnn/build/install/include -DMSHADOW_RABIT_PS=0 -DMSHADOW_DIST_PS=0 -DMSHADOW_USE_PASCAL=0 -DMXNET_USE_MKLDNN=1 -DUSE_MKL=1 -I/home/me/mxnet/src/operator/nn/mkldnn/ -I/home/me/mxnet/3rdparty/mkldnn/build/install/include -DMXNET_USE_OPENCV=1 -I/usr/local/include/opencv -I/usr/local/include -fopenmp -DMXNET_USE_OPERATOR_TUNING=1 -DMXNET_USE_LAPACK -DMSHADOW_USE_CUDNN=1 -I/home/me/mxnet/3rdparty/cub -DMXNET_ENABLE_CUDA_RTC=1 -DMXNET_USE_NCCL=0 -DMXNET_USE_LIBJPEG_TURBO=0" --generate-dependencies -MT build/src/operator/tensor/elemwise_unary_op_trig_gpu.o src/operator/tensor/elemwise_unary_op_trig.cu >build/src/operator/tensor/elemwise_unary_op_trig_gpu.d
If I break out (what I believe) to be all the include directories, I can pick out these directories:
-I/home/me/mxnet/3rdparty/mshadow/
-I/home/me/mxnet/3rdparty/dmlc-core/include -fPIC
-I/home/me/mxnet/3rdparty/tvm/nnvm/include
-I/home/me/mxnet/3rdparty/dlpack/include
-I/home/me/mxnet/3rdparty/tvm/include
-Iinclude -funroll-loops -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedefs -msse3 -mf16c
-I/usr/local/cuda/include -DMSHADOW_USE_CBLAS=1 -DMSHADOW_USE_MKL=0
-I/home/me/mxnet/3rdparty/mkldnn/build/install/include -DMSHADOW_RABIT_PS=0 -DMSHADOW_DIST_PS=0 -DMSHADOW_USE_PASCAL=0 -DMXNET_USE_MKLDNN=1 -DUSE_MKL=1
-I/home/me/mxnet/src/operator/nn/mkldnn/
-I/home/me/mxnet/3rdparty/mkldnn/build/install/include -DMXNET_USE_OPENCV=1
-I/usr/local/include/opencv
-I/usr/local/include -fopenmp -DMXNET_USE_OPERATOR_TUNING=1 -DMXNET_USE_LAPACK -DMSHADOW_USE_CUDNN=1
-I/home/me/mxnet/3rdparty/cub
When I look for cblas.h, I get see these copies:
(deepnets) me#Chanticleer:~/mxnet$ sudo find /home -name 'cblas.h'
[sudo] password for me:
/home/me/anaconda2/pkgs/openblas-0.3.3-h9ac9557_1001/include/cblas.h
/home/me/anaconda2/pkgs/lapack-3.6.1-ha44fe06_2/include/cblas.h
/home/me/anaconda2/pkgs/openblas-0.3.5-h9ac9557_1001/include/cblas.h
/home/me/anaconda2/envs/deepnets/include/cblas.h
/home/me/mxnet/julia/deps/cblas.h
(deepnets) me#Chanticleer:~/mxnet$ sudo find /usr -name 'cblas.h'
/usr/include/atlas/cblas.h
/usr/include/openblas/cblas.h
/usr/include/cblas.h
Clearly none of these seem to be where the Makefile has been directed to look. Do I need to change the Makefile in some way (how?), or do I need to put a copy of cblas.h in some other directory, or at least a soft link to it. If so, which directory and how?
If you're compiling with nvcc, you can just use the last include file, since it's in your include directory already, like this:
nvcc -I/usr/include <other stuff here...>
You don't have to do anything as drastic as manually copying; in fact I would really recommend against it because you're going to have to remember to re-do this when there's an update.
To answer your question about the makefile, if you were going to add the declaration I would say it's pretty common to see it being added to the $(CPPFLAGS) variable, which stands for C/C++ Preprocessor Flags. However, I would do this instead:
INCLUDE_DIRS = -I/usr/include
COMPILE.cpp = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE_DIRS) $(TARGET_ARCH) -c
OUTPUT_OPTION = -o $#
%.o: %.cpp
$(COMPILE.cpp) $(OUTPUT_OPTION) $^
The (proper) convention is for your users to be able to customize the $(CXX), $(CXXFLAGS), and $(CPPFLAGS) variables. Essentially, you want them to pick and customize their compiler, flags, and build options. Since you obviously need this include file, however (or you wouldn't have gotten this error), I would recommend setting it completely separately to avoid any confusion.
Anyways, good luck, man. I hope this helps.
I'm compiling KDBUS in my machine (x86-64, ubuntu 14.04). But this question is actually not related. This is a example. The first command fails, but the second succeeds. The success and failure depend on the order of -lm, and -lm. I saw this kinds of problem before. I could solved that problem manually. By this time, I want to know if there is a way to the first command succeeds without modifying the order of -lXXX ridiculously. Is there someone who know the way?
1.
gcc -L/usr/lib/x86_64-linux-gnu -std=gnu99 -Wall -Wextra -g -include /include/uapi/linux/memfd.h -I../samples/ -D_GNU_SOURCE -Wno-unused-parameter -Wmaybe-uninitialized -Wredundant-decls -Wcast-align -Wsign-compare -Wno-missing-field-initializers -pthread -lm -lcap kdbus-enum.o kdbus-util.o kdbus-test.o test-activator.o test-attach-flags.o test-benchmark.o test-bus.o test-chat.o test-connection.o test-daemon.o test-endpoint.o test-fd.o test-free.o test-match.o test-message.o test-metadata-ns.o test-monitor.o test-names.o test-policy.o test-policy-ns.o test-policy-priv.o test-sync.o test-timeout.o -o kdbus-test
kdbus-util.o: In function `do_cap_get_flag':
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1525: undefined reference to `cap_get_flag'
kdbus-util.o: In function `test_is_capable':
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1550: undefined reference to `cap_get_proc'
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1570: undefined reference to `cap_free'
test-benchmark.o: In function `dump_stats':
/harddisk/git/public/KDBUS/kdbus/test/test-benchmark.c:62: undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
.2
gcc -L/usr/lib/x86_64-linux-gnu -std=gnu99 -Wall -Wextra -g -include /include/uapi/linux/memfd.h -I../samples/ -D_GNU_SOURCE -Wno-unused-parameter -Wmaybe-uninitialized -Wredundant-decls -Wcast-align -Wsign-compare -Wno-missing-field-initializers -pthread kdbus-enum.o kdbus-util.o -lcap kdbus-test.o test-activator.o test-attach-flags.o test-benchmark.o -lm test-bus.o test-chat.o test-connection.o test-daemon.o test-endpoint.o test-fd.o test-free.o test-match.o test-message.o test-metadata-ns.o test-monitor.o test-names.o test-policy.o test-policy-ns.o test-policy-priv.o test-sync.o test-timeout.o -o kdbus-test
Added 1.
kdbus-test: $(OBJS)
#echo ' TARGET_LD $#'
#echo $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
This is the makefile for the above compile command. I think that this kinds of makefiles are common. How should I modify this makefile to work?
Added 2.
kdbus-test: $(OBJS)
#echo ' TARGET_LD $#'
#echo $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(Q)$(CC) $(CFLAGS) $^ -o $# $(LDFLAGS)
After I added the above additional question, I found that this code works. After the comment from Mike Kinghan and this working code, is it the right way to put the $LDFLAGS after object files generally?
I have been trying to install the HDF5 API in Windows using MinGW and Cygwin. I have given up on MinGW (after failing to compile HDF5-1.8.11 on it) because I need to use HDF5 on Fortran.
Using Cygwin with HDF5-1.8.11 produces errors when running the configure (bash) script and therefore it does not even start to compile. I read on this link that the HDF5-1.8 compiles on Cygwin including the Fortran module. I downloaded an older version (HDF5-1.8.0) and the configure works fine, but the compile (2nd make) gives the following error:
Making all in src
make[1]: Entering directory `/cygdrive/c/hdf5-1.8.0/src'
make all-am
make[2]: Entering directory `/cygdrive/c/hdf5-1.8.0/src'
/bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/cygdrive/c/cygwin/usr/include -DNDEBUG -UH5_DEBUG_API -ansi -pedantic -Wall -W -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -O3 -fomit-frame-pointer -finline-functions -MT H5Omtime.lo -MD -MP -MF .deps/H5Omtime.Tpo -c -o H5Omtime.lo H5Omtime.c
gcc -DHAVE_CONFIG_H -I. -I/cygdrive/c/cygwin/usr/include -DNDEBUG -UH5_DEBUG_API -ansi -pedantic -Wall -W -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -O3 -fomit-frame-pointer -finline-functions -MT H5Omtime.lo -MD -MP -MF .deps/H5Omtime.Tpo -c H5Omtime.c -o H5Omtime.o
In file included from H5private.h:29:0,
from H5Omtime.c:24:
H5public.h:154:18: warning: ISO C90 does not support ‘long long’ [-Wlong-long]
H5public.h:155:16: warning: ISO C90 does not support ‘long long’ [-Wlong-long]
H5Omtime.c: In function ‘H5O_mtime_decode’:
H5Omtime.c:194:9: warning: implicit declaration of function ‘tzset’ [-Wimplicit-function-declaration]
H5Omtime.c:194:9: warning: nested extern declaration of ‘tzset’ [-Wnested-externs]
H5Omtime.c:230:17: error: ‘timezone’ undeclared (first use in this function)
H5Omtime.c:230:17: note: each undeclared identifier is reported only once for each function it appears in
Makefile:813: recipe for target `H5Omtime.lo' failed
make[2]: *** [H5Omtime.lo] Error 1
make[2]: Leaving directory `/cygdrive/c/hdf5-1.8.0/src'
Makefile:488: recipe for target `all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory `/cygdrive/c/hdf5-1.8.0/src'
Makefile:410: recipe for target `all-recursive' failed
make: *** [all-recursive] Error 1
I would appreciate any help on this! Thanks!
I was able to reproduce this error. It seems that the configure script sets a number of #define flags which indicate the presence of the timezone global variable, which in reality is not present within the cygwin environment and is thus reported missing in the error message. By removing the #define H5_HAVE_TIMEZONE from the header file H5pubconf.h I was able to get rid of this error.
Unfortunately, then still another error occurs during the make process, which can also be avoided by removing the #define H5_HAVE_GETPWUID from the same header file H5pubconf.h.
Although this does not explain what really went wrong during configure, with these two modifications I am able to successfully compile the library.
Background
I'm trying to compile certain drivers within the Linux kernel: drm (drivers/gpu/drm/drm_drv.o) and radeon (drivers/gpu/drm/radeon/) gpu drivers. I'm using LLVM for the purposes of static analysis (tracking the arguments used in copy_to/from_user() invocations).
So far, I'm able to compile the actual modules using the Makefile as shown below:
make CC=clang CFLAGS=-emit-llvm drivers/gpu/drm/radeon/
But this does not actually emit any llvm bitcode -- I need the .bc files to run my pass with opt.
I only know how to generate .bc files when using clang directly (like below), but not with Makefiles...
clang -emit-llvm hello.c -c -o hello.bc
Since that worked, I grabbed the verbose output of the GNU make operation, changed gcc to clang, and ran it to create the .bc file, which also worked:
clang -emit-llvm [[tons of CFLAGS]] -c -o drm_drv.bc drivers/gpu/drm/drm_drv.c
The only problem with that is I can only process a single C file in the kernel module at a time. Also it's very tedious to do this approach...
Main Problem
Which brings me to my main question: How would you go about emitting llvm .bc bitcode files using the kernel's Makefiles?
Or, if .bc bitcode creation must be done on a per-file basis, then how would I link them all together at the end so that I can run an LLVM opt pass on the aggregate of all the .bc files in a kernel module?
The best way to get LLVM IR in bitcode form out of Clang is to do LTO with the -flto command line flag.
If you have multiple translation units you can combine them together using the llvm-lto tool to "link" the bitcode files. Typically it generates code, but you can get it to drop the merged LLVM IR module with the -save-merged-module flag.
But none of this is really a supported interface. If this is a significantly useful workflow, you should talk to the LLVM developers about supporting something more akin to ld's -r.
I used clang to instrument ext2 module. There are 3 things that you want to do:
1) convert .c into .bc
2) run your optimiser on .bc file, and create an ext2-opt.o file
3) create ext2-instrumented.ko file from the ext2-opt.o file.
along with this, you also require a linux version compiled with clang. I could get linux 4.17 compiled with clang version 3.8.1 after disabling few modules. you can get it here
now, lets move to step 1 - as you said, run Make in verbose mode
make V=1 M=fs/ext2
and grab all options that are spit out by Makefile. the default compiler will be gcc. replace gcc with clang, add --emit-llvm command, and replace .o with .bc. the resultant compilataion command on my machine looks like so:
cd ../../ && clang -emit-llvm -Wp,-MD,fs/ext2/.all.o.d -nostdinc -isystem /usr/local/bin/../lib/clang/3.8.1/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Qunused-arguments -Wno-unknown-warning-option -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -no-integrated-as -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -O2 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-variable -Wno-format-invalid-specifier -Wno-gnu -Wno-asm-operand-widths -Wno-initializer-overrides -fno-builtin -Wno-tautological-compare -mno-global-merge -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Wno-initializer-overrides -Wno-unused-value -Wno-format -Wno-unknown-warning-option -Wno-sign-compare -Wno-format-zero-length -Wno-uninitialized -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(all)" -D"KBUILD_MODNAME=KBUILD_STR(ext2)" -mcmodel=kernel -c -o fs/ext2_instrumented/all.bc fs/ext2/all.c && cd -
this will create a .bc file for you. note that I have changed the resultant .bc codes directory to ext2_instrumented, i.e. my bc file is not created in fs/ext2 but in another folder called fs/ext2_instrumented. this is my work folder. I want this folder to not have any .c files, only .bc files. I need this because the default KBuild system looks for .c files in a folder. More on this later.
Step 2: Run all optimisation passes on your resultant ext2-instrumented.bc file using opt command like so:
opt -load $(DIR)/build/FSlice.so -constprop -sccp -mergereturn -sink -licm -reg2mem all.bc -o all.inst.bc
llvm-link -o all.inst2.bc $(DIR)/build/libFSlice.bc all.inst.bc
clang -mcmodel=kernel -c all.inst2.bc -o all.o
this will result into a .o file, which we will now compile into a .ko file in the next step:
Step 3:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) ext2instrumented.ko
Kbuild system is tough to understand, and even tougher to make modifications on. I would recommend use this 2 folder hack (1st folder to create .bc file and second folder to create .o and .ko files). To summarise, here is my resultant makefile in ext2_instrumented folder:
DIR=/home/fslice/fslice
obj-m += ext2instrumented.o
ext2instrumented-objs := all.o
all:
cd ../../ && clang -emit-llvm -Wp,-MD,fs/ext2/.all.o.d -nostdinc -isystem /usr/local/bin/../lib/clang/3.8.1/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Qunused-arguments -Wno-unknown-warning-option -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -no-integrated-as -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -O2 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-variable -Wno-format-invalid-specifier -Wno-gnu -Wno-asm-operand-widths -Wno-initializer-overrides -fno-builtin -Wno-tautological-compare -mno-global-merge -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Wno-initializer-overrides -Wno-unused-value -Wno-format -Wno-unknown-warning-option -Wno-sign-compare -Wno-format-zero-length -Wno-uninitialized -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(all)" -D"KBUILD_MODNAME=KBUILD_STR(ext2)" -mcmodel=kernel -c -o fs/ext2_instrumented/all.bc fs/ext2/all.c && cd -
opt -load $(DIR)/build/FSlice.so -constprop -sccp -mergereturn -sink -licm -reg2mem all.bc -o all.inst.bc
llvm-link -o all.inst2.bc $(DIR)/build/libFSlice.bc all.inst.bc
clang -mcmodel=kernel -c all.inst2.bc -o all.o
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) ext2instrumented.ko
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
rm -rf *.bc
I am attempting to use Mingw-w64's 32-bit compiler (the i686-w64-mingw32 toolchain) to cross-compile the ICU library for Windows. The host is Ubuntu 12.10 64-bit.
The steps I have taken look something like this:
Grab the latest source code archive from here and extract it.
Make two copies of the source/ directory - one for the host and one for the target.
For the host build:
./configure ; make
For the target build:
./configure --host=i686-w64-mingw32 --with-cross-build=<host_source_dir>
...where <host_source_dir> is the directory from the previous step.
When I run make in the target source directory, compilation proceeds without any errors for a few moments and then throws this error:
i686-w64-mingw32-g++ -O2 -W -Wall -pedantic -Wpointer-arith -Wwrite-strings
-Wno-long-long -mthreads -o ../../bin/uconv.exe uconv.o uwmsg.o
-L../../lib -licuin50 -L../../lib -licuuc50 -L../../stubdata -licudt50
-lm uconvmsg/uconvmsg.a
uconv.o:uconv.cpp:(.text+0x2f): undefined reference to `_uconvmsg_dat'
What could be causing this error? I backed up a few lines and also noticed this:
pkgdata: i686-w64-mingw32-gcc -O2 -Wall -std=c99 -pedantic -Wshadow
-Wpointer-arith -Wmissing-prototypes -Wwrite-strings -mthreads -shared
-Wl,-Bsymbolic -Wl,--enable-auto-import -Wl,--out-implib=./all.lib -o
../lib/icudt50.dll ./out/tmp/icudt50l_dat.o
Cannot export icudt50_dat: symbol not found
collect2: ld returned 1 exit status
-- return status = 256
Error generating library file. Failed command: i686-w64-mingw32-gcc -O2 -Wall
-std=c99 -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes
-Wwrite-strings -mthreads -shared -Wl,-Bsymbolic -Wl,--enable-auto-import
-Wl,--out-implib=./all.lib -o ../lib/icudt50.dll ./out/tmp/icudt50l_dat.o
Error generating assembly code for data.
What am I doing wrong?
In order to debug your symbol problem just provide the flag -Wl,--trace-symbol=_uconvmsg_dat to i686-w64-mingw32-g++ like follows:
i686-w64-mingw32-g++ -O2 -W -Wall -pedantic -Wpointer-arith -Wwrite-strings
-Wno-long-long -mthreads -o ../../bin/uconv.exe uconv.o uwmsg.o
-L../../lib -licuin50 -L../../lib -licuuc50 -L../../stubdata -licudt50
-lm uconvmsg/uconvmsg.a -Wl,--trace-symbol=_uconvmsg_dat
So it turns out that the problem was indeed with the ICU source code. I'm not sure I understand exactly what the problem is, but thankfully someone else did and wrote three patches.
The first two apply to my question above:
icu4c-50_1_2-crossbuild.patch
icu4c-4_6_1-win32.patch
The third patch is used instead of the second in the list above when building for the x86_64 architecture:
icu4c-4_6_1-win64.patch
There does still seem to be a problem when running make install, but at least the source tree seems to build now.