[LLVMdev] Building LLVM on Windows

Alain Frisch alain.frisch at lexifi.com
Thu Jan 3 09:35:48 PST 2008


Thanks to recent changes in the SVN, I was able to successfully build 
LLVM under Windows in the following environments:

1. Cygwin;
2. MinGW/MSYS;
3. "gcc -mno-cygwin" (a.k.a MinGW on Cygwin).

For 3., I've had to make a few manual changes to the build system. Care 
is needed because non-Cygwin external commands require Windows paths and 
Cygwin's make does not like path names with colon in them (as in 
C:\...). Currently, the only such external command in LLVM's build seems 
to be tblgen.

I describe below what I've done in case others are interested (I believe 
that minimal fixes to the configure script would be enough to have 
everything work out of the box.)

The OCaml bindings needs some more work (I've haven't succeeded yet) to 
compile under Mingw:
- the statement CFLAGS+=... in bindings/ocaml/Makefile.ocaml is 
destroyed if we set CFLAGS in Makefile.config (this might be solved by 
using =? instead of = in Makefile.config);
- the variables OCAMLC, OCAMLOPT, OCAMLDEP in Makefile.config are 
Windows paths (they should be Cygwin paths);
- there should be quotes when adding to CFLAGS in Makefile.ocaml:
CFLAGS += -I"$(shell $(OCAMLC) -where)";
- use $(SYSPATH) as below for all the ocaml commands;
- replace .a with .lib in Makefile.ocaml;
- adapt llvm-config to produce .lib suffixes for --libnames;
- ... (probably other things)

* Run the configure script

CFLAGS=-mno-cygwin CXXFLAGS=-mno-cygwin ./configure --prefix=... 
--build=i686-pc-mingw32 --disable-threads --disable-ltdl-install

* Add the following lines to Makefile.config:

SYSPATH = $(shell echo $(1) | cygpath -m -f -)

(I could not figure out how to have the configure script pass CFLAGS and 
CXXFLAGS to Makefile.config. I've tried to add them on configure's 
command line and in the environment as above. Is this a bug?)

(The configure script could produce the SYSPATH above when asked to 
compile for MinGW on Cygwin, and just "SYSPATH = $(1)" otherwise.)

* Set variables in include/llvm/Config/config.h:


(The configure script find Cygwin libraries which should not be used 
here. When asked to compile for MinGW on Cygwin, it should not try to 
find those libraries.)

* Arrange so that Windows path are passed to the tblgen tool, using the 
SYSPATH function defined above (might be better to factorize all the 
calls to tblgen with such a function).

Index: lib/VMCore/Makefile
--- lib/VMCore/Makefile	(revision 45533)
+++ lib/VMCore/Makefile	(working copy)
@@ -21,7 +21,7 @@

  $(ObjDir)/Intrinsics.gen.tmp: $(ObjDir)/.dir $(INTRINSICTDS) $(TBLGEN)
  	$(Echo) Building Intrinsics.gen.tmp from Intrinsics.td
-	$(Verb) $(TableGen) $(INTRINSICTD) -o $@ -gen-intrinsic
+	$(Verb) $(TableGen) $(call SYSPATH, $(INTRINSICTD)) -o $(call SYSPATH, 
$@) -gen-intrinsic

  $(GENFILE): $(ObjDir)/Intrinsics.gen.tmp
  	$(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
Index: Makefile.rules
--- Makefile.rules	(revision 45533)
+++ Makefile.rules	(working copy)
@@ -483,8 +483,9 @@
  ProgInstall   = $(INSTALL) $(Install.StripFlag) -m 0755
  ScriptInstall = $(INSTALL) -m 0755
  DataInstall   = $(INSTALL) -m 0644
-TableGen      = $(TBLGEN) -I $(PROJ_SRC_DIR) -I$(PROJ_SRC_ROOT)/include \
-                -I $(PROJ_SRC_ROOT)/lib/Target
+TableGen      = $(TBLGEN) -I $(call SYSPATH, $(PROJ_SRC_DIR)) \
+                -I $(call SYSPATH, $(PROJ_SRC_ROOT)/include) \
+                -I $(call SYSPATH, $(PROJ_SRC_ROOT)/lib/Target)
  Archive       = $(AR) $(AR.Flags)
  LArchive      = $(LLVMToolDir)/llvm-ar rcsf
  ifdef RANLIB
@@ -1248,57 +1249,57 @@
  $(TARGET:%=$(ObjDir)/%GenRegisterNames.inc.tmp): \
  $(ObjDir)/%GenRegisterNames.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) register names with tblgen"
-	$(Verb) $(TableGen) -gen-register-enums -o $@ $<
+	$(Verb) $(TableGen) -gen-register-enums -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenRegisterInfo.h.inc.tmp): \
  $(ObjDir)/%GenRegisterInfo.h.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) register information header with tblgen"
-	$(Verb) $(TableGen) -gen-register-desc-header -o $@ $<
+	$(Verb) $(TableGen) -gen-register-desc-header -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenRegisterInfo.inc.tmp): \
  $(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) register info implementation with tblgen"
-	$(Verb) $(TableGen) -gen-register-desc -o $@ $<
+	$(Verb) $(TableGen) -gen-register-desc -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenInstrNames.inc.tmp): \
  $(ObjDir)/%GenInstrNames.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) instruction names with tblgen"
-	$(Verb) $(TableGen) -gen-instr-enums -o $@ $<
+	$(Verb) $(TableGen) -gen-instr-enums -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenInstrInfo.inc.tmp): \
  $(ObjDir)/%GenInstrInfo.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) instruction information with tblgen"
-	$(Verb) $(TableGen) -gen-instr-desc -o $@ $<
+	$(Verb) $(TableGen) -gen-instr-desc -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenAsmWriter.inc.tmp): \
  $(ObjDir)/%GenAsmWriter.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) assembly writer with tblgen"
-	$(Verb) $(TableGen) -gen-asm-writer -o $@ $<
+	$(Verb) $(TableGen) -gen-asm-writer -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenAsmWriter1.inc.tmp): \
  $(ObjDir)/%GenAsmWriter1.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) assembly writer #1 with tblgen"
-	$(Verb) $(TableGen) -gen-asm-writer -asmwriternum=1 -o $@ $<
+	$(Verb) $(TableGen) -gen-asm-writer -asmwriternum=1 -o $(call SYSPATH, 
$@) $<

  $(TARGET:%=$(ObjDir)/%GenCodeEmitter.inc.tmp): \
  $(ObjDir)/%GenCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) code emitter with tblgen"
-	$(Verb) $(TableGen) -gen-emitter -o $@ $<
+	$(Verb) $(TableGen) -gen-emitter -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenDAGISel.inc.tmp): \
  $(ObjDir)/%GenDAGISel.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) instruction selector implementation with tblgen"
-	$(Verb) $(TableGen) -gen-dag-isel -o $@ $<
+	$(Verb) $(TableGen) -gen-dag-isel -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenSubtarget.inc.tmp): \
  $(ObjDir)/%GenSubtarget.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) subtarget information with tblgen"
-	$(Verb) $(TableGen) -gen-subtarget -o $@ $<
+	$(Verb) $(TableGen) -gen-subtarget -o $(call SYSPATH, $@) $<

  $(TARGET:%=$(ObjDir)/%GenCallingConv.inc.tmp): \
  $(ObjDir)/%GenCallingConv.inc.tmp : %.td $(ObjDir)/.dir
  	$(Echo) "Building $(<F) calling convention information with tblgen"
-	$(Verb) $(TableGen) -gen-callingconv -o $@ $<
+	$(Verb) $(TableGen) -gen-callingconv -o $(call SYSPATH, $@) $<

  	-$(Verb) $(RM) -f $(INCFiles)

-- Alain

More information about the llvm-dev mailing list