Enable cross-compiling the clang plugin

RESOLVED FIXED in Firefox 44

Status

defect
RESOLVED FIXED
4 years ago
2 years ago

People

(Reporter: Ehsan, Unassigned)

Tracking

unspecified
mozilla44
Dependency tree / graph

Firefox Tracking Flags

(firefox44 fixed)

Details

Attachments

(1 attachment, 1 obsolete attachment)

In order to make the clang plugin work on Linux builders targeting OS X builds, we need to enable proper cross compiling by making this library be built for host.

I added a HostSharedLibrary template and tried to implement the underlying machinery but what I have doesn't work, and I can't figure out why.  I need help from someone who knows how this stuff works.
Posted patch WIP for bug 1204763 (obsolete) — Splinter Review
glandium, can you please take a look to find out what I'm doing wrong, please?  Thanks!
Attachment #8661044 - Flags: feedback?(mh+mozilla)
This is what I get when building with this on OSX:

 0:25.76 Reticulating splines...
 0:37.18 Finished reading 2469 moz.build files in 3.35s
 0:37.18 Processed into 9025 build config descriptors in 3.31s
 0:37.18 Backend executed in 4.48s
 0:37.18 2441 total backend files; 2441 created; 0 updated; 0 unchanged; 0 deleted; 124 -> 892 Makefile
 0:37.18 Total wall time: 11.42s; CPU time: 9.88s; Efficiency: 86%; Untracked: 0.28s
 0:38.24 From dist/private: Kept 0 existing; Added/updated 0; Removed 0 files and 0 directories.
 0:38.24 From dist/public: Kept 0 existing; Added/updated 0; Removed 0 files and 0 directories.
 0:38.24 From dist/sdk: Kept 0 existing; Added/updated 0; Removed 0 files and 0 directories.
 0:38.24 From dist/branding: Kept 0 existing; Added/updated 5; Removed 0 files and 0 directories.
 0:38.24 From dist/xpi-stage: Kept 2 existing; Added/updated 0; Removed 0 files and 0 directories.
 0:38.27 From dist/bin: Kept 190 existing; Added/updated 95; Removed 1 files and 0 directories.
 0:38.43 From dist/idl: Kept 0 existing; Added/updated 1142; Removed 0 files and 0 directories.
 0:38.78 From dist/include: Kept 1926 existing; Added/updated 2644; Removed 0 files and 0 directories.
 0:45.16 From _tests: Kept 28 existing; Added/updated 40890; Removed 0 files and 0 directories.
 0:45.44 libclang-plugin.a
 0:45.52 Executing: ar crs libclang-plugin.a
 0:45.53 ar: no archive members specified
 0:45.53 usage:  ar -d [-TLsv] archive file ...
 0:45.53   ar -m [-TLsv] archive file ...
 0:45.53   ar -m [-abiTLsv] position archive file ...
 0:45.53   ar -p [-TLsv] archive [file ...]
 0:45.53   ar -q [-cTLsv] archive file ...
 0:45.53   ar -r [-cuTLsv] archive file ...
 0:45.53   ar -r [-abciuTLsv] position archive file ...
 0:45.53   ar -t [-TLsv] archive [file ...]
 0:45.53   ar -x [-ouTLsv] archive [file ...]
 0:45.53 make[5]: *** [libclang-plugin.a] Error 1
 0:45.53 make[4]: *** [build/clang-plugin/host] Error 2
 0:45.53 make[3]: *** [export] Error 2
 0:45.53 make[2]: *** [default] Error 2
 0:45.53 make[1]: *** [realbuild] Error 2
 0:45.53 make: *** [build] Error 2
 0:45.58 0 compiler warnings present.
(In reply to Ehsan Akhgari (don't ask for review please) from comment #1)
> Created attachment 8661044 [details] [diff] [review]
> WIP for bug 1204763
> 
> glandium, can you please take a look to find out what I'm doing wrong,
> please?  Thanks!

The answer is "simply" that config.mk/rules.mk doesn't have rules to build host shared libraries. And IIRC, there are assumptions in place about that never being supported, so you're kind of entering a minefield. What's the timeframe to get this working?
Attachment #8661044 - Flags: feedback?(mh+mozilla)
(In reply to Mike Hommey [:glandium] from comment #3)
> (In reply to Ehsan Akhgari (don't ask for review please) from comment #1)
> > Created attachment 8661044 [details] [diff] [review]
> > WIP for bug 1204763
> > 
> > glandium, can you please take a look to find out what I'm doing wrong,
> > please?  Thanks!
> 
> The answer is "simply" that config.mk/rules.mk doesn't have rules to build
> host shared libraries. And IIRC, there are assumptions in place about that
> never being supported, so you're kind of entering a minefield. What's the
> timeframe to get this working?

Hmm, there is no strict timeline but I would prefer to do it very soon (i.e., in the order of the next few weeks.)

Is there an easy work around for this?  I think all I really need is to use the host compiler and linker, other stuff such as CFLAGS etc already don't really come from our build system.
Flags: needinfo?(mh+mozilla)
> Is there an easy work around for this?

Short of an explicit local rule in the corresponding Makefile.in, there is no way around going all the way to support host shared libraries.
Flags: needinfo?(mh+mozilla)
Can you please help with what that local rule would look like?
Flags: needinfo?(mh+mozilla)
It looks like the following does the trick, assuming that we get the CXXFLAGS/LDFLAGS right:

diff --git a/build/clang-plugin/Makefile.in b/build/clang-plugin/Makefile.in
--- a/build/clang-plugin/Makefile.in
+++ b/build/clang-plugin/Makefile.in
@@ -8,16 +8,18 @@ MOZ_OPTIMIZE =
 include $(topsrcdir)/config/config.mk
 
 # In the current moz.build world, we need to override essentially every
 # variable to limit ourselves to what we need to build the clang plugin.
 OS_CXXFLAGS := $(LLVM_CXXFLAGS) -fno-rtti -fno-exceptions
 OS_COMPILE_CXXFLAGS :=
 OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
 DSO_LDOPTS := -shared
+# Use the host compiler instead of the target compiler.
+CXX := $(HOST_CXX)
 
 # Use the default OS X deployment target to enable using the libc++ headers
 # correctly.  Note that the binary produced here is a host tool and doesn't need
 # to be distributed.
 MACOSX_DEPLOYMENT_TARGET :=
 
 # Temporarily relax the requirements for libstdc++ symbol versions on static
 # analysis plugin in order to use a recent clang by accepting libstdc++ from
I guess that's less gross than whatever local rule we could come up with.
Flags: needinfo?(mh+mozilla)
Attachment #8661044 - Attachment is obsolete: true
Blocks: 1208787
Blocks: 1208794
Comment on attachment 8666402 [details] [diff] [review]
Enable cross compiling the clang plugin for OS X on Linux

Review of attachment 8666402 [details] [diff] [review]:
-----------------------------------------------------------------

::: build/clang-plugin/Makefile.in
@@ +17,5 @@
> +ifdef CROSS_COMPILE
> +ifeq ($(HOST_OS_ARCH)_$(OS_TARGET),Linux_Darwin)
> +# Use the host compiler instead of the target compiler.
> +CXX := $(HOST_CXX)
> +# Don't use --uselist with expandlibs_exec.py.

mmmm what led you to this?
Flags: needinfo?(ehsan)
(In reply to Mike Hommey [:glandium] from comment #10)
> Comment on attachment 8666402 [details] [diff] [review]
> Enable cross compiling the clang plugin for OS X on Linux
> 
> Review of attachment 8666402 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: build/clang-plugin/Makefile.in
> @@ +17,5 @@
> > +ifdef CROSS_COMPILE
> > +ifeq ($(HOST_OS_ARCH)_$(OS_TARGET),Linux_Darwin)
> > +# Use the host compiler instead of the target compiler.
> > +CXX := $(HOST_CXX)
> > +# Don't use --uselist with expandlibs_exec.py.
> 
> mmmm what led you to this?

Without this, I get:

[root@taskcluster-worker clang-plugin]# make libclang-plugin.dylib
libclang-plugin.dylib
rm -f libclang-plugin.dylib
/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/_virtualenv/bin/python /home/worker/workspace/gecko-dev/config/expandlibs_exec.py --uselist -- /home/worker/workspace/gecko-dev/clang/bin/clang++ -Qunused-arguments  -I/home/worker/workspace/gecko-dev/clang/include  -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -O3 -fomit-frame-pointer -std=c++11 -fno-exceptions -fno-rtti -fPIC -ffunction-sections -fdata-sections -Wcast-qual -fno-rtti -fno-exceptions -fomit-frame-pointer -Werror -fPIC -shared -o libclang-plugin.dylib  clang-plugin.o   -lz -lpthread -lrt -ldl -lm -L/home/worker/workspace/gecko-dev/clang/lib -lLLVMOption -lLLVMBitReader -lLLVMMCParser -lLLVMAsmParser -lLLVMAnalysis -lLLVMMC -lLLVMCore -lLLVMSupport -lclangASTMatchers      -dynamiclib -install_name @executable_path/libclang-plugin.dylib -compatibility_version 1 -current_version 1 -single_module
Executing: ../../../clang/bin/clang++ -Qunused-arguments -I/home/worker/workspace/gecko-dev/clang/include -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -O3 -fomit-frame-pointer -std=c++11 -fno-exceptions -fno-rtti -fPIC -ffunction-sections -fdata-sections -Wcast-qual -fno-rtti -fno-exceptions -fomit-frame-pointer -Werror -fPIC -shared -o libclang-plugin.dylib -Wl,-filelist,/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/tmppeYLJm.list -lz -lpthread -lrt -ldl -lm -L/home/worker/workspace/gecko-dev/clang/lib -lLLVMOption -lLLVMBitReader -lLLVMMCParser -lLLVMAsmParser -lLLVMAnalysis -lLLVMMC -lLLVMCore -lLLVMSupport -lclangASTMatchers -dynamiclib -install_name @executable_path/libclang-plugin.dylib -compatibility_version 1 -current_version 1 -single_module
/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/tmppeYLJm.list:
    clang-plugin.o

/usr/bin/ld:/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/tmppeYLJm.list: file format not recognized; treating as linker script
/usr/bin/ld:/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/tmppeYLJm.list:2: syntax error
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libclang-plugin.dylib] Error 1

Note the -Wl,-filelist argument.  On Linux the clang driver doesn't know what to do with that, and constructs a linker command like this:

"/usr/bin/ld" "--hash-style=gnu" "--no-add-needed" "--build-id" "--eh-frame-hdr" "-m" "elf_x86_64" "-shared" "-o" "libclang-plugin.dylib" "/usr/lib/../lib64/crti.o" "/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/../../../clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.7.3/crtbeginS.o" "-L/home/worker/workspace/gecko-dev/clang/lib" "-L/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/../../../clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.7.3" "-L/lib/../lib64" "-L/usr/lib/../lib64" "-L/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/../../../clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.7.3/../../.." "-L/home/worker/workspace/gecko-dev/clang/bin/../lib" "-L/lib" "-L/usr/lib" "-filelist" "/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/tmppeYLJm.list" "-lz" "-lpthread" "-lrt" "-ldl" "-lm" "-lLLVMOption" "-lLLVMBitReader" "-lLLVMMCParser" "-lLLVMAsmParser" "-lLLVMAnalysis" "-lLLVMMC" "-lLLVMCore" "-lLLVMSupport" "-lclangASTMatchers" "-lstdc++" "-lm" "-lgcc_s" "-lc" "-lgcc_s" "/home/worker/workspace/gecko-dev/obj-x86_64-apple-darwin/build/clang-plugin/../../../clang/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.7.3/crtendS.o" "/usr/lib/../lib64/crtn.o"

And then the linker gets confused about the -filelist argument.
Flags: needinfo?(ehsan)
Comment on attachment 8666402 [details] [diff] [review]
Enable cross compiling the clang plugin for OS X on Linux

Review of attachment 8666402 [details] [diff] [review]:
-----------------------------------------------------------------

::: build/clang-plugin/Makefile.in
@@ +13,5 @@
>  OS_COMPILE_CXXFLAGS :=
>  OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
>  DSO_LDOPTS := -shared
>  
> +ifdef CROSS_COMPILE

technically, the condition that follows guarantees that CROSS_COMPILE is set, so this is redundant.

@@ +14,5 @@
>  OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
>  DSO_LDOPTS := -shared
>  
> +ifdef CROSS_COMPILE
> +ifeq ($(HOST_OS_ARCH)_$(OS_TARGET),Linux_Darwin)

s/OS_TARGET/OS_ARCH/ (not strictly necessary, but it avoids bystanders wondering why it's HOST_OS_ARCH and OS_TARGET)

@@ +17,5 @@
> +ifdef CROSS_COMPILE
> +ifeq ($(HOST_OS_ARCH)_$(OS_TARGET),Linux_Darwin)
> +# Use the host compiler instead of the target compiler.
> +CXX := $(HOST_CXX)
> +# Don't use --uselist with expandlibs_exec.py.

Aaah, I see. Can you add a comment along these lines:
# expandlibs doesn't know the distinction between host and target toolchains, and on cross linux/darwin builds, the options to give to the linker for file lists differ between both, so don't use file lists.
Attachment #8666402 - Flags: review?(mh+mozilla) → review+
https://hg.mozilla.org/mozilla-central/rev/00a10127e2ce
https://hg.mozilla.org/mozilla-central/rev/6a326cba82ee
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla44
Product: Core → Firefox Build System
You need to log in before you can comment on or make changes to this bug.