wxWidgets library build garbled file name in linker - wxwidgets

On attempting to build wxWidgets 3.1.0 libraries, I am getting this error
ar: gcc_mswu\moolib_fontmap.o: No such file or directory
A file does exists with a slightly different spelling
Directory of C:\Users\James\code\wxwidgets-3.1.0\build\msw\gcc_mswu
2017-01-05 02:01 PM 98,886 monolib_fontmap.o
It looks like a typo in the makefile, or like a letter is missed reading the makefile. Is that possible?
Except: if I redirect the console output to a file and open in an editor , the correct spelling shows up:
So the correct command is going to the linker, but the linker is looking for a garbled filename!
Here is the complete recipe for what I am doing:
Download wxWidgets source code from https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.0/wxWidgets-3.1.0.7z
Unpack to a folder. On my system, I use C:\Users\James\code\wxwidgets-3.1.0
Open a command window.
cd to the code::blocks mingw folder. On my system this is C:\Program Files (x86)\CodeBlocks16\MinGW
Type mingwvars.bat
cd to wxwidgets folder. On my system C:\Users\James\code\wxwidgets-3.1.0
cd to ./build/msw
Type mingw32-make SHELL=CMD.exe -j4 -f makefile.gcc BUILD=release UNICODE=1 SHARED=0 MONOLITHIC=1

This seems to be the same problem as the one mentioned in the wiki. Apparently there is a bug in mingw32-make with very long command lines which makes it (sometimes?) eat characters in them...
Yes. Applying the recipe in the link you posted fixed the problem. Here are the details:
modify makefile.gcc as following:
From:
ifeq ($(MONOLITHIC),1)
ifeq ($(SHARED),0)
$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).a: $(MONOLIB_OBJECTS)
if exist $# del $#
ar rcu $# $(MONOLIB_OBJECTS)
ranlib $#
endif
endif
Replace second occurence of $(MONOLIB_OBJECTS) with gcc_mswu\monolib*.o:
ifeq ($(MONOLITHIC),1)
ifeq ($(SHARED),0)
$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).a: $(MONOLIB_OBJECTS)
if exist $# del $#
ar rcu $# gcc_mswu\\monolib*.o
ranlib $#
endif
endif

Related

Error in including homemade Fortran modules and libraries in Makefile

I am trying to build a very simple Makefile, that intends to use a homemade library (libf904QC.a) made of Fortran modules. The library is in /usr/local/lib64 whereas the corresponding .mod files are in /usr/local/include/f904QC
Here is the Makefile
# Makefile
NAME=NPManip
FFLAGS= -ffpe-trap=overflow -c -O3
LFLAGS=
PATH2LIB=/usr/local/lib64/
INCLUDEDIR=/usr/local/include/f904QC/
#
LIB=-L$(PATH2LIB) -I$(INCLUDEDIR) -lf904QC.a
OBJS = \
tools_NPManip.o\
NPManip.o
%.o: %.f90
gfortran $(LIB) $(FFLAGS) $*.f90
NPM: $(OBJS)
gfortran $(LFLAGS) $(OBJS) $(LIB) -o $(NAME)
clean:
#if test -e $$HOME/bin/$(NAME); then \
rm $$HOME/bin/$(NAME); \
fi
rm *.o *.mod
mrproper: clean
rm $(NAME)
install:
ln -s $(shell pwd)/$(NAME) $$HOME/bin/.
I get the following error message :
gfortran tools_NPManip.o NPManip.o -L/usr/local/lib64/ -I/usr/local/include/f904QC/ -lf904QC.a -o NPManip
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: cannot find -lf904QC.a
collect2: error: ld returned 1 exit status
make: * [NPM] Erreur 1
Where is the mistake? It is not obvious to me since libf904QC.o is actually located in /usr/local/lib64, which is defined by the -L option.
Thnak you for your help
You should specify either the full path to the library /usr/local/lib64/libf904QC.a or alternatively -L/usr/local/lib64 -lf90QC, without the .a in that case. From man ld:
-l namespec
--library=namespec
Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of
times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it
will search the library path for a file called libnamespec.a.
-L searchdir
--library-path=searchdir
Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts. You may use
this option any number of times. The directories are searched in the order in which they are specified on the command
line. Directories specified on the command line are searched before the default directories. All -L options apply to
all -l options, regardless of the order in which the options appear. -L options do not affect how ld searches for a
linker script unless -T option is specified.

MinGW linking dynamic library with bad name

I am using MinGW64 (Windows 7) without MSYS and I have the following problem:
I have one dll, written in C99, which has to have the .mexw64 suffix so it can be used by Matlab. I would like to be able to link this dll form another dll (mexw64) dynamically but gcc won't allow me to link directly. I cannot do static linking, because both dlls have many functions of the same name which can be hidden by not exporting their symbols when creating the shared library.
So far, I have tried:
To create a symbolic link (with correct suffix and preffix) using mklink. This works, but I was not able to run mklink from the makefile. Maybe it is due to the fact I am not using MSYS which could have ln -s (I havent checked).
To do the copy of the first dll and correcting the suffix and prefix. This worked better than I expected, because on runtime the second dll actually uses the original .mexw64 and not the dll copy. I guess it is just because the .mexw64 is found first, but why is that .mexw64 searched in the first place? How the system know it is actually a dll?
My question is, is this correct/safe enough? Are there any other options?
Thanks for comments.
You should build a proper implib, either as a linker output or from a .def.
Linker:
$ gcc -shared -o testimpl.mexw64 testimpl.c -Wl,--out-implib,libtestimpl.a
$ dlltool -I libtestimpl.a
testimpl.mexw64
Or create a .def file, specifying an explicit LIBRARY:
$ cat testimpl.def
LIBRARY testimpl.mexw64
EXPORTS
test #1
$ dlltool -d testimpl.def -l libtestimpl.a
$ dlltool -I libtestimpl.a
testimpl.mexw64
And finally, link stuff:
$ gcc -o test.exe test.c libtestimpl.a
# or
$ gcc -o test.exe test.c -L. -ltestimpl
$ grep testimpl.mexw64 test.exe
Binary file test.exe matches

Extra build/missing object files with header-tracking Makefile

I have written a (GNU make) Makefile designed to perform automatic dependency tracking in header includes. Everything works great except that upon typing make a second time, the entire code base rebuilds. Only typing make the third time and successive times gives the message that nothing is to be done.
SRCDIR := src
INCDIR := inc
ifeq ($(DEBUG),1)
OBJDIR := debug_obj
BINDIR := debug_bin
else
OBJDIR := obj
BINDIR := bin
endif
BINS := prog1 prog2 prog3 prog4
SRCS := $(wildcard $(SRCDIR)/*.cpp)
OBJS := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(SRCS:.cpp=.o))
DEPS := $(OBJS:.o=.d)
CC := g++
COMMON_FLAGS := -Wall -Wextra -Werror -std=c++11 -pedantic
ifeq ($(DEBUG),1)
CXX_FLAGS := $(COMMON_FLAGS) -Og -g
else
CXX_FLAGS := $(COMMON_FLAGS) -O3 -D NDEBUG
endif
all: $(addprefix $(BINDIR)/,$(BINS)) | $(BINDIR)
$(OBJDIR) $(BINDIR):
# mkdir -p $#;
$(BINDIR)/%: $(OBJDIR)/%.o | $(BINDIR)
$(CC) $(CPP_FLAGS) $< -o $#;
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $(OBJDIR)
$(CC) $(CPP_FLAGS) -MMD -MP -c $< -o $#;
-include $(DEPS)
.PHONY: all clean
clean:
- rm -f $(OBJS);
- rm -f $(DEPS);
- rm -f $(addprefix $(BINDIR)/,$(BINS));
- rmdir $(OBJDIR) $(BINDIR) 2> /dev/null || true
Clearly some dependency had changed, so I tried running make -n -d | grep 'newer' following the first invocation of make, which shows this:
Prerequisite obj/prog1.o' is newer than targetbin/prog1'.
Prerequisite obj/prog2.o' is newer than targetbin/prog2'.
Prerequisite obj/prog3.o' is newer than targetbin/prog3'.
Prerequisite obj/prog4.o' is newer than targetbin/prog4'.
And ls -la obj/*
Showed the existence of the dependency (*.d) files but not the object (*.o) files. I assume that this is related to how g++ -MMD -MP works, but despite the apparent absence of object files, binaries are present after the first make.
The answer to this question suggests that both are generated at the same time, and man g++ does not dispute this as far as I can tell.
I've read a couple other questions and answers related to automatic dependency tracking, but I don't see this issue arising. Why is this happening? Can you suggest a fix?
Update
A more careful look at the first invocation of make shows this unexpected (to me) line at the end:
rm obj/prog1.o obj/prog2.o obj/prog3.o obj/prog4.o
That answers one question but raises another.
Update
I also found this in the debugging output.
Considering target file `prog1'.
File `prog1' does not exist.
make: *** No rule to make target `prog1'. Stop.
No implicit rule found for `prog1'.
Finished prerequisites of target file `prog1'.
Must remake target `prog1'.
For which I note that prog1 is missing the bin/ prefix. Nothing explains why the first run removes the object files, but the second run leaves them, however. That seems to be at the heart of the issue.
make was treating the object files as intermediates and deleting them accordingly. Adding:
.SECONDARY: $(OBJS)
solved the problem. I do not know why it was doing this the first invocation but not the second invocation. Comments are welcome.
The reason that the .o files are not present is that they're considered intermediate files so make deletes them. However, that shouldn't cause any problems in your build, because as long as make can envision the intermediate file it will realize it doesn't need to be rebuilt if its prerequisites are older than its parents (in this case, as long as prog1 is newer than prog1.cpp for example).
I was not able to reproduce your experience with the second build rebuilding everything. More details will be needed. The output you showed is not interesting because that's just saying that make does NOT need to rebuild the .o file (it's newer than the prerequisite). You need to find the lines in the output that explain why make does need to rebuild the .o file. If you provide that info we may be able to help.
Just a couple of comments on your makefile: first, I don't think it's a good idea to force the mkdir rule to always succeed. If the mkdir fails you WANT your build to fail. Probably you did this so it would not be a problem if the directory already exists, but that's not needed because the mkdir -p invocation will never fail just because the directory exists (but it will fail if the directory can't be created for other reasons such as permissions). Also you can combine those into a single rule with multiple targets:
$(BINDIR) $(OBJDIR):
#mkdir -p $#
Next, you don't need the semicolons in your command lines and in fact, adding them will cause your builds to be slightly slower.
Finally, a small nit, but the correct order of options in the compile line is -c -o $# $<; the source file is not (this is a common misconception) an argument to the -c option. The -c option, like -E, -s, etc. tells the compiler what output to create; in the case of -c it means compile into an object file. Those options do not take arguments. The filename is a separate argument.

How to specify compiler in makefile?

All,
I'm trying to modify a Makefile to use a embedded cross compiler instead of the PC's compiler. The Makfile does not have the normal CC or CXX variables. In fact, it appears that is calls another makefile with the variable '#${MAKE}'. How can I override the '#${MAKE}' variable to force the makefile to use a diffent compliler?
Thanks In Advance,
# GNU Make solution makefile autogenerated by Premake
# Type "make help" for usage help
ifndef config
config=debug
endif
export config
PROJECTS := json openjaus
.PHONY: all clean help $(PROJECTS)
all: $(PROJECTS)
json:
#echo "==== Building json ($(config)) ===="
#${MAKE} --no-print-directory -C .build -f json.make
openjaus: json
#echo "==== Building openjaus ($(config)) ===="
#${MAKE} --no-print-directory -C .build -f openjaus.make
I edited the Makefile based on Rob's comments, now I'm receiving the message below, not sure what to do?
make[1]: Nothing to be done for `/home/botbear/openwrt/trunk/staging_dir/toolchain-arm_v6k_gcc-linaro_uClibc-0.9.32_eabi/bin/arm-openwrt-linux-uclibcgnueabi-g++'.
You'd have to look inside json.make and openjaus.make to see how they build programs. If they use the conventional variables, you might be able to do something like:
${MAKE} CC=/usr/bin/gcc-arm CXX=/usr/bin/g++-arm --no-parent-directory ...

Makefile to archive/link together auto-generated source files

Basically, I have a file 'blah.txt'. That files gets parsed by a 'compiler' and from it will generate N output .c files. I want a makefile that will from that .txt file generate the c files then compile all of them and archive them in a libmystuff.a
I tought of something like this :
all: dogen libmystuff.a
dogen: source.txt
mycompiler $^
libmystuff.a: $(addsuffix .o, $(shell ls *.c))
$(AR) rcs $# $^
.PHONY: dogen
But obviously that doesn't work because the dependencies are evaluated at the start and at that point the *.c just doesn't yield anything yet since they don't exist.
Does anyone see how to accomplish that (without listing all the generated *.c explicitely) ?
Use sentry "makefile" to force make to re-read makefile and substitute correct list at *.c:
include sources-sentry
sources-sentry: source.txt
mycompiler $^
touch $#
libmystuff.a: $(addsuffix .o, $(shell ls *.c))
$(AR) rcs $# $^
include directive is used to include other makefiles (just like C's #include). It has a nice pecularity that if makefile it includes is a target itself, make program first considers it as a target and tries to update. If it is not up-to-date, make invokes the commands needed to update it and then re-reads makefile, substituting all the variables again.
Thus, if source.txt changed since the last time you processed it (the time being recorded as timestamp of sources-sentry file), the sources will be updated and make will be re-invoked, the *.c being substituted to the updates set of c-files.
Pavel Shved is right(*), you must rerun Make. Here is a trick I'm rather proud of. It will handle dependencies on objects that may not yet exist, and won't run unnecessarily.
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
all: libmystuff.a
ifeq ($(MAKELEVEL),0)
libmystuff.a: source.txt
mycompiler $^
#$(MAKE) -s $#
else
libmystuff.a: $(OBJECTS)
$(AR) rcs $# $^
endif
(*) My old nemesis, we meet again.
EDIT:
If some other make calls this make... I hadn't thought of that. But I think this will solve it:
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
all: libmystuff.a
libmystuff.a: source.txt
mycompiler $^
#$(MAKE) -s phonyLib
.PHONY: phonyLib
phonyLib: $(OBJECTS)
$(AR) rcs libmystuff.a $^
(Yes, I know, if you feel an urge to build a file called "phonyLib" you won't be able to do it with this makefile, but let's not be perverse.)
If your .c files are only produced by the .txt, then you can let the libmystuff.a depend on the txt, and evaluate the $(shell ls *.c) in the rule body instead.