Skip to content

Cross compile rpmalloc with ninja #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jneuhauser opened this issue Nov 27, 2019 · 7 comments
Closed

Cross compile rpmalloc with ninja #124

jneuhauser opened this issue Nov 27, 2019 · 7 comments
Assignees
Milestone

Comments

@jneuhauser
Copy link
Contributor

jneuhauser commented Nov 27, 2019

Hello,

same problem as mjansson/rpmalloc-benchmark#4.

How can i define a sysroot or a toolchain for cross compiling?
I´ve seen that build/ninja/generator.py supports some environment variables, but they have no influence in the build process.

Thanks

@mjansson
Copy link
Owner

The ninja generator does indeed not support cross-compilation at the moment, but I will be happy to try to improve it so it does.

@mjansson mjansson self-assigned this Nov 28, 2019
@mjansson mjansson added this to the 1.4.1 milestone Nov 28, 2019
@jneuhauser
Copy link
Contributor Author

jneuhauser commented Nov 28, 2019

I´ve created a quick and dirty patch for cross compilation with gcc.

With that patch i can compile rpmalloc inside the OpenWRT buildroot.
Here is my custom package repo: https://github.com/jneuhauser/openwrt-allocator-packages/blob/master/rpmalloc/

--- a/build/ninja/gcc.py
+++ b/build/ninja/gcc.py
@@ -13,11 +13,11 @@ class GCCToolchain(toolchain.Toolchain):
     self.toolchain = ''
     self.includepaths = []
     self.libpaths = libpaths
-    self.ccompiler = 'gcc'
-    self.cxxcompiler = 'g++'
-    self.archiver = 'ar'
-    self.linker = 'gcc'
-    self.cxxlinker = 'g++'
+    self.ccompiler = os.environ.get('CC') or 'gcc'
+    self.cxxcompiler = os.environ.get('CXX') or 'g++'
+    self.archiver = os.environ.get('AR') or 'ar'
+    self.linker = os.environ.get('CC') or 'gcc'
+    self.cxxlinker = os.environ.get('CXX') or 'g++'
 
     #Command definitions
     self.cccmd = '$toolchain$cc -MMD -MT $out -MF $out.d $includepaths $moreincludepaths $cflags $carchflags $cconfigflags $cmoreflags -c $in -o $out'
@@ -113,15 +113,15 @@ class GCCToolchain(toolchain.Toolchain):
     writer.variable('link', self.linker)
     writer.variable('includepaths', self.make_includepaths(self.includepaths))
     writer.variable('moreincludepaths', '')
-    writer.variable('cflags', self.cflags)
-    writer.variable('cxxflags', self.cxxflags)
+    writer.variable('cflags', self.cflags + (os.environ.get('CFLAGS') or '').split())
+    writer.variable('cxxflags', self.cxxflags + (os.environ.get('CXXFLAGS') or '').split())
     writer.variable('carchflags', '')
     writer.variable('cconfigflags', '')
     writer.variable('cmoreflags', self.cmoreflags)
-    writer.variable('arflags', self.arflags)
+    writer.variable('arflags', self.arflags + (os.environ.get('ARFLAGS') or '').split())
     writer.variable('ararchflags', '')
     writer.variable('arconfigflags', '')
-    writer.variable('linkflags', self.linkflags)
+    writer.variable('linkflags', self.linkflags + (os.environ.get('LDFLAGS') or '').split())
     writer.variable('linkarchflags', '')
     writer.variable('linkconfigflags', '')
     writer.variable('libs', '')

Probably appending the FLAGS in the writer is too late, but to honor my flags from the build system i need it to be the last.

@mjansson
Copy link
Owner

Nice solution, I generalized the flag handling a bit and added it to the clang toolchain as well, check the mjansson/cross-compile branch and see if it still works for you.

@jneuhauser
Copy link
Contributor Author

jneuhauser commented Nov 28, 2019

I tested your cross-compile branch with gcc as cross toolchain but the CFLAGS aren´t honored...
I´ve no clue why... My quick and dirty solution worked like a charm.

The OpenWRT buildroot has a own flag "-fhonour-copts" for gcc that prints "note: someone does not honour COPTS correctly, passed 0 times" if it is not set to verify the flags are honored.

Do you have any thoughts about that?

Apart from not honoring CFLAGS, i think the following should be changed:

--- a/build/ninja/gcc.py
+++ b/build/ninja/gcc.py
@@ -34,6 +34,7 @@ class GCCToolchain(toolchain.Toolchain):
                    '-fno-trapping-math', '-ffast-math']
     self.cwarnflags = ['-Wextra', '-Wall', '-Werror']
     self.cmoreflags = []
+    self.cxxmoreflags = []
     self.mflags = []
     self.arflags = []
     self.linkflags = []
@@ -118,7 +119,7 @@ class GCCToolchain(toolchain.Toolchain):
     writer.variable('carchflags', '')
     writer.variable('cconfigflags', '')
     writer.variable('cmoreflags', self.cmoreflags + (os.environ.get('CFLAGS') or '').split())
-    writer.variable('cxxmoreflags', self.cmoreflags + (os.environ.get('CXXFLAGS') or '').split())
+    writer.variable('cxxmoreflags', self.cxxmoreflags + (os.environ.get('CXXFLAGS') or '').split())
     writer.variable('arflags', self.arflags)
     writer.variable('ararchflags', '')
     writer.variable('arconfigflags', '')

Or like this:

--- a/build/ninja/gcc.py
+++ b/build/ninja/gcc.py
@@ -118,7 +119,7 @@ class GCCToolchain(toolchain.Toolchain):
     writer.variable('carchflags', '')
     writer.variable('cconfigflags', '')
     writer.variable('cmoreflags', self.cmoreflags + (os.environ.get('CFLAGS') or '').split())
-    writer.variable('cxxmoreflags', self.cmoreflags + (os.environ.get('CXXFLAGS') or '').split())
+    writer.variable('cxxmoreflags', (os.environ.get('CXXFLAGS') or '').split())
     writer.variable('arflags', self.arflags)
     writer.variable('ararchflags', '')
     writer.variable('arconfigflags', '')

@jneuhauser
Copy link
Contributor Author

In the build.ninja file, there are some occurrences of "cmoreflags" that override the "cmoreflags" that are set from the environment in the configure step.

The OpenWRT buildroot has a own flag "-fhonour-copts" for gcc that prints "note: someone does not honour COPTS correctly, passed 0 times" if it is not set.
This is to verify by the build system that the set flags are honored.

Easiest solution to fix that would be to use another var instead of "cmoreflags" that gets not overridden.

Here is my generated build.ninja:

ninja_required_version = 1.3

# configure.py arguments
configure_args = --toolchain gcc --config release --arch generic

# configure options
configure_target = linux
configure_host = linux
configure_env = ARFLAGS=' ' AR=mips-openwrt-linux-musl-gcc-ar $
    CC=mips-openwrt-linux-musl-gcc CFLAGS='-Os -pipe -mno-branch-likely $
    -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts $
    -Wno-error=unused-but-set-variable -Wno-error=unused-result $
    -msoft-float -mips16 -minterlink-mips16 $
    -ffile-prefix-map=/home/johann/dev/openwrt/openwrt/build_dir/target-mips_24kc_musl/rpmalloc-1.4.0=rpmalloc-1.4.0 $
    -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 $
    -Wl,-z,now -Wl,-z,relro '$ 
configure_toolchain = gcc
configure_archs = generic
configure_configs = release

buildpath = build/ninja/linux
target = linux
config = 
toolchain = 
cc = mips-openwrt-linux-musl-gcc
cxx = mips-openwrt-linux-musl-g++
ar = mips-openwrt-linux-musl-gcc-ar
link = mips-openwrt-linux-musl-gcc
includepaths = -I.
moreincludepaths = 
cflags = -DRPMALLOC_COMPILE=1 -funit-at-a-time -fstrict-aliasing $
    -fno-math-errno -ffinite-math-only -funsafe-math-optimizations $
    -fno-trapping-math -ffast-math -D_GNU_SOURCE=1 -Wextra -Wall -Werror $
    -std=c11
cxxflags = -DRPMALLOC_COMPILE=1 -funit-at-a-time -fstrict-aliasing $
    -fno-math-errno -ffinite-math-only -funsafe-math-optimizations $
    -fno-trapping-math -ffast-math -D_GNU_SOURCE=1 -Wextra -Wall -Werror $
    -std=gnu++14
carchflags = 
cconfigflags = 
cmoreflags = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc $
    -fno-caller-saves -fno-plt -fhonour-copts $
    -Wno-error=unused-but-set-variable -Wno-error=unused-result $
    -msoft-float -mips16 -minterlink-mips16 $
    -ffile-prefix-map=/home/johann/dev/openwrt/openwrt/build_dir/target-mips_24kc_musl/rpmalloc-1.4.0=rpmalloc-1.4.0 $
    -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 $
    -Wl,-z,now -Wl,-z,relro
cxxmoreflags = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc $
    -fno-caller-saves -fno-plt -fhonour-copts $
    -Wno-error=unused-but-set-variable -Wno-error=unused-result $
    -msoft-float -mips16 -minterlink-mips16 $
    -ffile-prefix-map=/home/johann/dev/openwrt/openwrt/build_dir/target-mips_24kc_musl/rpmalloc-1.4.0=rpmalloc-1.4.0 $
    -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 $
    -Wl,-z,now -Wl,-z,relro
arflags = 
ararchflags = 
arconfigflags = 
armoreflags = 
linkflags = -pthread
linkarchflags = 
linkconfigflags = 
linkmoreflags = $
    -L/home/johann/dev/openwrt/openwrt/staging_dir/target-mips_24kc_musl/usr/lib $
    -L/home/johann/dev/openwrt/openwrt/staging_dir/target-mips_24kc_musl/lib $
    -L/home/johann/dev/openwrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-8.3.0_musl/usr/lib $
    -L/home/johann/dev/openwrt/openwrt/staging_dir/toolchain-mips_24kc_gcc-8.3.0_musl/lib $
    -znow -zrelro
libs = 
libpaths = 
configlibpaths = 
archlibs = 
oslibs = -ldl

pool serial_pool
  depth = 1
rule copy
  command = cp -f $in $out
  description = COPY $in -> $out
rule mkdir
  command = mkdir -p $out
  description = MKDIR $out
rule cc
  command = $toolchain$cc -MMD -MT $out -MF $out.d $includepaths $
      $moreincludepaths $cflags $carchflags $cconfigflags $cmoreflags -c $
      $in -o $out
  description = CC $in
  depfile = $out.d
  deps = gcc
rule cxx
  command = $toolchain$cxx -MMD -MT $out -MF $out.d $includepaths $
      $moreincludepaths $cxxflags $carchflags $cconfigflags $cxxmoreflags $
      -c $in -o $out
  description = CXX $in
  depfile = $out.d
  deps = gcc
rule ar
  command = rm -f $out && $toolchain$ar crsD $arflags $ararchflags $
      $arconfigflags $armoreflags $out $in
  description = LIB $out
rule link
  command = $toolchain$link $libpaths $configlibpaths $linkflags $
      $linkarchflags $linkconfigflags $linkmoreflags -o $out $in $libs $
      $archlibs $oslibs
  description = LINK $out
rule so
  command = $toolchain$link $libpaths $configlibpaths $linkflags $
      $linkarchflags $linkconfigflags $linkmoreflags -o $out $in $libs $
      $archlibs $oslibs
  description = SO $out

build $buildpath/release/generic/rpmalloc-7c2f09b/rpmalloc-65d008a.o: cc $
    rpmalloc/rpmalloc.c
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
build $buildpath/release/generic/rpmalloc-7c2f09b/librpmalloc.a: ar $
    $buildpath/release/generic/rpmalloc-7c2f09b/rpmalloc-65d008a.o
build lib/linux/release: mkdir
build lib/linux/release/generic: mkdir | lib/linux/release
build lib/linux/release/generic/librpmalloc.a: copy $
    $buildpath/release/generic/rpmalloc-7c2f09b/librpmalloc.a || $
    lib/linux/release/generic

build $buildpath/release/generic/rpmalloc-cccf0ca/rpmalloc-a2b50b2.o: cc $
    rpmalloc/rpmalloc.c
  carchflags = -DBUILD_DYNAMIC_LINK=1 -fPIC
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
build $buildpath/release/generic/rpmalloc-cccf0ca/librpmalloc.so: so $
    $buildpath/release/generic/rpmalloc-cccf0ca/rpmalloc-a2b50b2.o
  linkconfigflags = -shared
  configlibpaths = -Llib/linux -Llib/linux/generic -Llib/linux/release $
      -Llib/linux/release/generic
build bin/linux/release: mkdir
build bin/linux/release/generic: mkdir | bin/linux/release
build bin/linux/release/generic/librpmalloc.so: copy $
    $buildpath/release/generic/rpmalloc-cccf0ca/librpmalloc.so || $
    bin/linux/release/generic

build $buildpath/release/generic/rpmalloc-5aa0e6/rpmalloc-a2b50b2.o: cc $
    rpmalloc/rpmalloc.c
  carchflags = -DBUILD_DYNAMIC_LINK=1 -fPIC
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_PRELOAD=1 -DENABLE_OVERRIDE=1
build $buildpath/release/generic/rpmalloc-5aa0e6/librpmallocwrap.so: so $
    $buildpath/release/generic/rpmalloc-5aa0e6/rpmalloc-a2b50b2.o
  linkconfigflags = -shared
  configlibpaths = -Llib/linux -Llib/linux/generic -Llib/linux/release $
      -Llib/linux/release/generic
build bin/linux/release/generic/librpmallocwrap.so: copy $
    $buildpath/release/generic/rpmalloc-5aa0e6/librpmallocwrap.so || $
    bin/linux/release/generic

build $buildpath/release/generic/rpmalloc-a8e50b6/rpmalloc-65d008a.o: cc $
    rpmalloc/rpmalloc.c
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_PRELOAD=1 -DENABLE_OVERRIDE=1
build $buildpath/release/generic/rpmalloc-a8e50b6/librpmallocwrap.a: ar $
    $buildpath/release/generic/rpmalloc-a8e50b6/rpmalloc-65d008a.o
build lib/linux/release/generic/librpmallocwrap.a: copy $
    $buildpath/release/generic/rpmalloc-a8e50b6/librpmallocwrap.a || $
    lib/linux/release/generic

build $buildpath/release/generic/test-57ec084/thread-35aa063.o: cc $
    test/thread.c
  moreincludepaths = -Irpmalloc -Itest
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_ASSERTS=1 -DENABLE_STATISTICS=1
build $buildpath/release/generic/test-57ec084/main-28e5055.o: cc test/main.c
  moreincludepaths = -Irpmalloc -Itest
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_ASSERTS=1 -DENABLE_STATISTICS=1
build $buildpath/release/generic/test-57ec084/rpmalloc-test: link $
    $buildpath/release/generic/test-57ec084/thread-35aa063.o $
    $buildpath/release/generic/test-57ec084/main-28e5055.o | $
    lib/linux/release/generic/librpmalloc.a
  libs = -lrpmalloc
  configlibpaths = -Llib/linux -Llib/linux/generic -Llib/linux/release $
      -Llib/linux/release/generic
build bin/linux/release/generic/rpmalloc-test: copy $
    $buildpath/release/generic/test-57ec084/rpmalloc-test || $
    bin/linux/release/generic

build $buildpath/release/generic/test-7e8c09f/thread-35aa063.o: cc $
    test/thread.c
  moreincludepaths = -Irpmalloc -Itest
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_ASSERTS=1 -DENABLE_STATISTICS=1
build $buildpath/release/generic/test-7e8c09f/main-override-7531094.o: cxx $
    test/main-override.cc
  moreincludepaths = -Irpmalloc -Itest
  cconfigflags = -DBUILD_RELEASE=1 -O3 -g -funroll-loops
  cmoreflags = -DENABLE_ASSERTS=1 -DENABLE_STATISTICS=1
build $buildpath/release/generic/test-7e8c09f/rpmallocwrap-test: link $
    $buildpath/release/generic/test-7e8c09f/thread-35aa063.o $
    $buildpath/release/generic/test-7e8c09f/main-override-7531094.o | $
    lib/linux/release/generic/librpmallocwrap.a
  libs = -lrpmallocwrap
  configlibpaths = -Llib/linux -Llib/linux/generic -Llib/linux/release $
      -Llib/linux/release/generic
  link = mips-openwrt-linux-musl-g++
build bin/linux/release/generic/rpmallocwrap-test: copy $
    $buildpath/release/generic/test-7e8c09f/rpmallocwrap-test || $
    bin/linux/release/generic

@mjansson
Copy link
Owner

Thanks, will add these changes later tonight

@jneuhauser
Copy link
Contributor Author

Proper solution is provided in #126

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants