Cross compiling KDE / Nokia N900

2009-12-23 Thread Alexander Neundorf
On Tuesday 22 December 2009, Thiago Macieira wrote:
...
 We've been successful at getting Qt to cross compile for the N900. It works
 much faster and requires no VM. In fact, it works with build farms too, so
 get all the benefits of a normal build.

 Any chance we can get an effort started to make KDE cross-compileable?

Yes, it's also on my todo, but it would be really nice if somebody else could 
actually do the work and I would just guide throught the necessary steps.

There are mainly three things which lead to problems when cross compiling:
1) try to build and run executable during the configure check
2) running executables during the configure step to find out information
3) running executables during the build step to do something.

1) is the hardest one. If somebody does a try_run (check_c_source_runs()) in a 
cross compile, it will build the executable, but it will not try to run it 
(since it can't, in general). Instead cmake will provide a template cmake 
script file prepared so that the expected values from the try_run() can be 
entered there manually. Also the compiled executable is made available, so 
that the developer can take it, run it on the target and in this way figure 
out the result which have to go into the prepared cmake script file. This 
file than has to be preloaded into cmake using -C on the next cmake run.
Doing this for all try_run()s is actual work.

2) We do this e.g. for Qt (FindQt4.cmake calls qmake), we query kde-config4, 
some find-modules call pkg-config (I'm not sure how to handle pkg-config when 
cross compiling, some env.vars could be set so that it finds only in the 
target root dir, ...). All these steps could be in some way done differently 
when cross compiling (e.g. only try to find qmake and then expect that the 
headers will be in the qmake_dir/../include etc. 
This can be guarded in 
if(CMAKE_CROSSCOMPILING)
   ...
endif(CMAKE_CROSSCOMPILING)


3) execute tools build during the build.
This is not a real problem, it's just a bit of work. We already export our 
libraries in kdelibs (KDELibs4LibraryTargets.cmake), and also separate from 
this our executable targets (KDELibs4ToolsTargets.cmake).
For cross compiling, these executable targets have to be available from a 
native build, and then this file can be loaded into the cross-compiling 
kdelibs and used there in the add_custom_commands/add_custom_targets().
Again this needs some 
if (CMAKE_CROSSCOMPILING) guards, most probably mainly in KDE4Macros.cmake, 
but then it should work.

 PS: maybe move this discussion to kde-buildsystem? Hereby I give my ok to
 move my part of the thread out of ev-membership.

Done :-)

Alex


___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Alexander Neundorf
On Wednesday 23 December 2009, Pino Toscano wrote:
 Hi,

 Alle mercoledì 23 dicembre 2009, Alexander Neundorf ha scritto:
  Yes, it's also on my todo, but it would be really nice if somebody else
   could actually do the work and I would just guide throught the
  necessary steps.
 
  There are mainly three things which lead to problems when cross
  compiling: 1) try to build and run executable during the configure check
  [...]
 
  1) is the hardest one. If somebody does a try_run (check_c_source_runs())
   in a cross compile, it will build the executable, but it will not try to
   run it (since it can't, in general). Instead cmake will provide a
  template cmake script file prepared so that the expected values from the
  try_run() can be entered there manually. Also the compiled executable is
  made available, so that the developer can take it, run it on the target
  and in this way figure out the result which have to go into the prepared
  cmake script file. This file than has to be preloaded into cmake using -C
  on the next cmake run. Doing this for all try_run()s is actual work.

 I think this point could be solved if cmake would have the distinction
 between host (the platform it is building for) and build (the platform
 it is building on) compilers (of course, in case of no crosscompilation,
 host and build stuff would be the same).

This is the case since cmake 2.6.0 :-)
You can check 
if (CMAKE_CROSSCOMPILING)
 ...

and you have CMAKE_SYSTEM_NAME (target host) and CMAKE_HOST_SYSTEM_NAME (build 
host), if not cross compiling both are the same.

 For example, take the check_c_source_runs() example, and assume I'm
 crosscompiling on i386 (build gcc: cc) for arm (host cc: arm-linux-cc):
 check_c_source_runs() would be compiled using the build compiler (cc), so
 it can be run later.

Do you mean that even when cross compiling the i386 gcc should be used for 
check_c_source_runs() ?
This wouldn't make sense. The sources must be built using the target compiler 
(arm_linux-cc), since
-host and target compiler may be completely different compilers (think gcc and 
sdcc, or msvc and gcc)
-being able to compile and link the source with the host (i386) compiler 
doesn't tell you anything about whether it would also link on the target 
system
-running it in the build host environment doesn't tell you anything about the 
target environment

 This would have the advantage I could force the use of the build compiler
 for intermediate build steps, for example a custom target which has to
 compile some executable and run it to get the input files for other
 targets. This proposal would also avoid the template cmake script with the
 expected values and using CMAKE_CROSSCOMPILING in such situations.

 Would it feasible to do?

No, I don't think so. It must be done with the target compiler.

Something what might be feasible would be to add special support for executing 
executables via some wrapper (e.g. upload it to the target, execute it and 
return results, run it via wine, etc.).

Alex
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Pino Toscano
Alle mercoledì 23 dicembre 2009, Alexander Neundorf ha scritto:
 On Wednesday 23 December 2009, Pino Toscano wrote:
  Hi,
 
  Alle mercoledì 23 dicembre 2009, Alexander Neundorf ha scritto:
   Yes, it's also on my todo, but it would be really nice if somebody else
could actually do the work and I would just guide throught the
   necessary steps.
  
   There are mainly three things which lead to problems when cross
   compiling: 1) try to build and run executable during the configure
   check [...]
  
   1) is the hardest one. If somebody does a try_run
   (check_c_source_runs()) in a cross compile, it will build the
   executable, but it will not try to run it (since it can't, in general).
   Instead cmake will provide a template cmake script file prepared so
   that the expected values from the try_run() can be entered there
   manually. Also the compiled executable is made available, so that the
   developer can take it, run it on the target and in this way figure out
   the result which have to go into the prepared cmake script file. This
   file than has to be preloaded into cmake using -C on the next cmake
   run. Doing this for all try_run()s is actual work.
 
  I think this point could be solved if cmake would have the distinction
  between host (the platform it is building for) and build (the
  platform it is building on) compilers (of course, in case of no
  crosscompilation, host and build stuff would be the same).
 
 This is the case since cmake 2.6.0 :-)
 You can check
 if (CMAKE_CROSSCOMPILING)
  ...
 
 and you have CMAKE_SYSTEM_NAME (target host) and CMAKE_HOST_SYSTEM_NAME
  (build host), if not cross compiling both are the same.

I know cmake can do cross compiling this way (I do that at work), but it's far 
from being pain-free.

  For example, take the check_c_source_runs() example, and assume I'm
  crosscompiling on i386 (build gcc: cc) for arm (host cc: arm-linux-cc):
  check_c_source_runs() would be compiled using the build compiler (cc), so
  it can be run later.
 
 Do you mean that even when cross compiling the i386 gcc should be used for
 check_c_source_runs() ?
 This wouldn't make sense. The sources must be built using the target
  compiler (arm_linux-cc), since
 -host and target compiler may be completely different compilers (think gcc
  and sdcc, or msvc and gcc)
 -being able to compile and link the source with the host (i386) compiler
 doesn't tell you anything about whether it would also link on the target
 system
 -running it in the build host environment doesn't tell you anything about
  the target environment

Those points are valid, although there cold be situations where you want to do 
that anyway: for example, a small program that #include some version.h-like 
header, and outputs different stuff depending on different #if VERSION_MAJOR  
4 ... #elif VERSION_MAJOR  2 ... etc. This is so simple no compiler/toolchain 
could get it wrong.

Furthermore, there's still the other case of usefulness for having build and 
host compilers separated:

  This would have the advantage I could force the use of the build compiler
  for intermediate build steps, for example a custom target which has to
  compile some executable and run it to get the input files for other
  targets.

-- 
Pino Toscano


signature.asc
Description: This is a digitally signed message part.
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Alexander Neundorf
On Wednesday 23 December 2009, Pino Toscano wrote:
 Alle mercoledì 23 dicembre 2009, Alexander Neundorf ha scritto:
...
  and you have CMAKE_SYSTEM_NAME (target host) and CMAKE_HOST_SYSTEM_NAME
   (build host), if not cross compiling both are the same.

 I know cmake can do cross compiling this way (I do that at work), but it's
 far from being pain-free.

Can you please share your experiences, what works nice, what could need 
improvement, what doesn't work ?

...
 Those points are valid, although there cold be situations where you want to
 do that anyway: for example, a small program that #include some
 version.h-like header, and outputs different stuff depending on different
 #if VERSION_MAJOR  4 ... #elif VERSION_MAJOR  2 ... etc. This is so
 simple no compiler/toolchain could get it wrong.

Yes, there are probably situations where it would work, but since it wouldn't 
work in general, cmake AFAIK will not support this, since every case where it 
then does not work may get reported as a bug.
(something which doesn't always work but only in most cases is considered 
broken by Kitware)

 Furthermore, there's still the other case of usefulness for having build
 and host compilers separated:
   This would have the advantage I could force the use of the build
   compiler for intermediate build steps, for example a custom target
   which has to compile some executable and run it to get the input files
   for other targets.

Yes.
The issue with this is that right now it is one of the basic assumptions of 
cmake that you have _one_ compiler doing one build.
E.g. the CMakeCache.txt is valid for just one compiler. Everything contained 
in it can potentially be wrong for a second compiler for the same language.
So, adding this capability to cmake would be AFAICT a _lot_ of work.

Alex
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Thiago Macieira
Em Quarta-feira 23. Dezembro 2009, às 11.06.18, Alexander Neundorf escreveu:
 Yes, it's also on my todo, but it would be really nice if somebody else
  could actually do the work and I would just guide throught the necessary
  steps.
 
 There are mainly three things which lead to problems when cross compiling:
 1) try to build and run executable during the configure check
 2) running executables during the configure step to find out information
 3) running executables during the build step to do something.
 
 1) is the hardest one. If somebody does a try_run (check_c_source_runs())
  in a cross compile, it will build the executable, but it will not try to
  run it (since it can't, in general). Instead cmake will provide a template
  cmake script file prepared so that the expected values from the try_run()
  can be entered there manually. Also the compiled executable is made
  available, so that the developer can take it, run it on the target and in
  this way figure out the result which have to go into the prepared cmake
  script file. This file than has to be preloaded into cmake using -C on the
  next cmake run. Doing this for all try_run()s is actual work.

Indeed. Autoconf's solution to the problem is that an AC_CHECK_RUNS macro has 
three possible outcomes:
1) it runs
2) it doesn't run
3) it is being cross-compiled

This tri-state is what we need in CMake and what we need to fix in KDE (all of 
the checks).

Maybe CMake could also learn of scratchbox-like builds: i.e. cross-compiling, 
but the target executable can be run (maybe with an additional tool). For 
example, suppose we cross-compile for Windows using mingw32-g++. It is 
possible to run the resulting executable with Wine. For the N900, it's 
possible to execute the ARM executable with qemu / scratchbox. I don't know 
how difficult this would be, though.

Note that this is still a cross-compilation build, since non-native 
executables may have a performance penalty. The following point is important:

 2) We do this e.g. for Qt (FindQt4.cmake calls qmake), we query
  kde-config4, some find-modules call pkg-config (I'm not sure how to handle
  pkg-config when cross compiling, some env.vars could be set so that it
  finds only in the target root dir, ...). All these steps could be in some
  way done differently when cross compiling (e.g. only try to find qmake and
  then expect that the headers will be in the qmake_dir/../include etc.
 This can be guarded in
 if(CMAKE_CROSSCOMPILING)
...
 endif(CMAKE_CROSSCOMPILING)

You have to distinguish between host tools and target tools. The output of a 
Qt cross-compilation is that qmake, moc, uic, uic3 are host executables, 
whereas the libraries are target binaries (designer, assistant, etc. are not 
built, but if they were, they'd be target too). Interestingly, qdbusxml2cpp 
and qdbuscpp2xml are host tools, but qdbus and qdbusviewer are target ones.

So we need to be able to run host executables even in a cross-compilation. And 
we need to be able to create host executables for our own builds too, and run 
them.

As for pkg-config, it's also a host tool. The difference is you set some 
environment variables telling pkg-config where the cross-compilation root is, 
so that it may find the correct .pc files. Note, however, that the latest 
version of pkg-config (0.23) has a bug that makes it unusable for cross-
compilation. Upstream has fixed it already, but no new release has happened. 
You need to ensure your distribution has packaged the patch.

So the rule of thumb is: would this tool be in the main package or in the -
devel/-dev package for my library?

 3) execute tools build during the build.
 This is not a real problem, it's just a bit of work. We already export
  our libraries in kdelibs (KDELibs4LibraryTargets.cmake), and also separate
  from this our executable targets (KDELibs4ToolsTargets.cmake).
 For cross compiling, these executable targets have to be available from a
 native build, and then this file can be loaded into the cross-compiling
 kdelibs and used there in the add_custom_commands/add_custom_targets().
 Again this needs some
 if (CMAKE_CROSSCOMPILING) guards, most probably mainly in KDE4Macros.cmake,
 but then it should work.

Same as above.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
  PGP/GPG: 0x6EF45358; fingerprint:
  E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358


signature.asc
Description: This is a digitally signed message part.
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Alexander Neundorf
On Wednesday 23 December 2009, Thiago Macieira wrote:
 Em Quarta-feira 23. Dezembro 2009, às 11.06.18, Alexander Neundorf escreveu:
  Yes, it's also on my todo, but it would be really nice if somebody else
   could actually do the work and I would just guide throught the
  necessary steps.
 
  There are mainly three things which lead to problems when cross
  compiling: 1) try to build and run executable during the configure check
  2) running executables during the configure step to find out information
  3) running executables during the build step to do something.
 
  1) is the hardest one. If somebody does a try_run (check_c_source_runs())
   in a cross compile, it will build the executable, but it will not try to
   run it (since it can't, in general). Instead cmake will provide a
  template cmake script file prepared so that the expected values from the
  try_run() can be entered there manually. Also the compiled executable is
  made available, so that the developer can take it, run it on the target
  and in this way figure out the result which have to go into the prepared
  cmake script file. This file than has to be preloaded into cmake using -C
  on the next cmake run. Doing this for all try_run()s is actual work.

 Indeed. Autoconf's solution to the problem is that an AC_CHECK_RUNS macro
 has three possible outcomes:
   1) it runs
   2) it doesn't run
   3) it is being cross-compiled

 This tri-state is what we need in CMake and what we need to fix in KDE (all
 of the checks).

It does that basically. CMake always builds the executable, if not cross 
compiling, it tries to execute it, which fails or succeeds, if cross 
compiling, it doesn't try to execute it but leaves the result to the 
user/developer.

 Maybe CMake could also learn of scratchbox-like builds: i.e.
 cross-compiling, but the target executable can be run (maybe with an
 additional tool). For example, suppose we cross-compile for Windows using
 mingw32-g++. It is possible to run the resulting executable with Wine. For
 the N900, it's possible to execute the ARM executable with qemu /
 scratchbox. I don't know how difficult this would be, though.

 Note that this is still a cross-compilation build, since non-native
 executables may have a performance penalty. The following point is
 important:
  2) We do this e.g. for Qt (FindQt4.cmake calls qmake), we query
   kde-config4, some find-modules call pkg-config (I'm not sure how to
  handle pkg-config when cross compiling, some env.vars could be set so
  that it finds only in the target root dir, ...). All these steps could be
  in some way done differently when cross compiling (e.g. only try to find
  qmake and then expect that the headers will be in the
  qmake_dir/../include etc. This can be guarded in
  if(CMAKE_CROSSCOMPILING)
 ...
  endif(CMAKE_CROSSCOMPILING)

 You have to distinguish between host tools and target tools. The output of
 a Qt cross-compilation is that qmake, moc, uic, uic3 are host executables,
 whereas the libraries are target binaries (designer, assistant, etc. are
 not built, but if they were, they'd be target too). Interestingly,
 qdbusxml2cpp and qdbuscpp2xml are host tools, but qdbus and qdbusviewer are
 target ones.

 So we need to be able to run host executables even in a cross-compilation.

Yes, this is possible.
With cmake you can specifiy a CMAKE_FIND_ROOT_PATH, which is used as prefix to 
all search paths, i.e. it should point to the location where the target 
environment is installed:
http://www.cmake.org/Wiki/CMake_Cross_Compiling#Searching_and_finding_external_software

You can specifiy for the find_xxx() calls whether they should look in the 
ROOT_PATH or in the normal dirs.
For executables the default is to look in the normal dirs, for libs and header 
the default is to look in the ROOT_PATH dirs.
This can be specified for each find_xxx() call separately.

 And we need to be able to create host executables for our own builds too,
 and run them.

This has to be done in a separate build tree with cmake (or reuse an existing 
build host installation).

 As for pkg-config, it's also a host tool. The difference is you set some
 environment variables telling pkg-config where the cross-compilation root
 is, so that it may find the correct .pc files. Note, however, that the

Locally I have a patch for FindPkgConfig.cmake, which sets PKG_CONFIG_LIBDIR 
and PKG_CONFIG_PATH when cross compiling to point only inside the ROOT_PATH 
(i.e. the target environment).
Does that sound reasonable or would this be wrong ?

Alex
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Thiago Macieira
Em Quarta-feira 23. Dezembro 2009, às 14.29.48, Alexander Neundorf escreveu:
  And we need to be able to create host executables for our own builds too,
  and run them.
 
 This has to be done in a separate build tree with cmake (or reuse an
  existing build host installation).

That's a bit too much work. When cross-compiling, sometimes we need to compile 
a program to do extra work. Sometimes that program is installed, other times 
it isn't (example: meinproc).

So we need host targets as well as cross-compilation targets.

I agree this is much more complex, as many tests would need to be duplicated. 
It's like qmake's debug-and-release mode, which basically runs everything in 
two separate passes.

  As for pkg-config, it's also a host tool. The difference is you set some
  environment variables telling pkg-config where the cross-compilation root
  is, so that it may find the correct .pc files. Note, however, that the
 
 Locally I have a patch for FindPkgConfig.cmake, which sets
  PKG_CONFIG_LIBDIR and PKG_CONFIG_PATH when cross compiling to point only
  inside the ROOT_PATH (i.e. the target environment).
 Does that sound reasonable or would this be wrong ?

My script for cross-compiling sets this:
PKG_CONFIG_LIBDIR=/opt/maemo/arm-none-linux-gnueabi/libc/usr/lib/pkgconfig
PKG_CONFIG_SYSROOT_DIR=/opt/maemo/arm-none-linux-gnueabi/libc
PATH=/opt/teambuilder2/bin:/opt/maemo/bin:$PATH
export PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR PATH

It's the SYSROOT variable that is necessary but triggers the bug.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
  PGP/GPG: 0x6EF45358; fingerprint:
  E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358


signature.asc
Description: This is a digitally signed message part.
___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


Re: Cross compiling KDE / Nokia N900

2009-12-23 Thread Alexander Neundorf
On Wednesday 23 December 2009, Thiago Macieira wrote:
 Em Quarta-feira 23. Dezembro 2009, às 14.29.48, Alexander Neundorf escreveu:
   And we need to be able to create host executables for our own builds
   too, and run them.
 
  This has to be done in a separate build tree with cmake (or reuse an
   existing build host installation).

 That's a bit too much work. When cross-compiling, sometimes we need to
 compile a program to do extra work. Sometimes that program is installed,
 other times it isn't (example: meinproc).

 So we need host targets as well as cross-compilation targets.

s/we need/it would be nice to have/.

There are two options:
- we could just require that an installed kdelibs is required for cross 
compiling KDE
- we can introduce a custom target build_tools or something like that which 
depends on all the tools required for the cross-build. Then everybody would 
need to create a native build tree and build just this target there (make 
build_tools), and then point the cross-build to this native build-tree (via 
a cmake or environment variable or maybe it can be found automatically).

Both options can work and are real-world tested, and both options are maybe 
more work than having separate target platforms in one build tree.

 I agree this is much more complex, as many tests would need to be
 duplicated. It's like qmake's debug-and-release mode, which basically runs
 everything in two separate passes.

But practically this does not really matter, since AFAIK adding support for 
having multiple toolchains in one buildtree is not on the near-term roadmap 
for CMake. There are two ways to change this:
1) submit a patch which adds this functionality (well, patch, I think it 
would be a major piece of work), which passes all tests, works in all cases, 
etc.
2) get Kitware to implement it, easiest way is a payed contract

   As for pkg-config, it's also a host tool. The difference is you set
   some environment variables telling pkg-config where the
   cross-compilation root is, so that it may find the correct .pc files.
   Note, however, that the
 
  Locally I have a patch for FindPkgConfig.cmake, which sets
   PKG_CONFIG_LIBDIR and PKG_CONFIG_PATH when cross compiling to point only
   inside the ROOT_PATH (i.e. the target environment).
  Does that sound reasonable or would this be wrong ?

 My script for cross-compiling sets this:
 PKG_CONFIG_LIBDIR=/opt/maemo/arm-none-linux-gnueabi/libc/usr/lib/pkgconfig
 PKG_CONFIG_SYSROOT_DIR=/opt/maemo/arm-none-linux-gnueabi/libc
 PATH=/opt/teambuilder2/bin:/opt/maemo/bin:$PATH
 export PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR PATH

 It's the SYSROOT variable that is necessary but triggers the bug.

This is what my patch currently does:

+# When crosscompiling, pkg_config should not search for packages of the host
+# system, but for the target system. To do this, there is the environment
+# variable PKG_CONFIG_LIBDIR, which was added to pkg_config explicitely for
+# crosscompiling. Additionally PKG_CONFIG_PATH is set empty, otherwise these
+# directories are searched before PKG_CONFIG_LIBDIR (at least here with
+# version 0.21).
+# So set this here to point inside the CMAKE_FIND_ROOT_PATH so it can find
+# only packages for the target system when crosscompiling. Alex
+set(pkgconfigLibDir)
+if(CMAKE_CROSSCOMPILING  AND  CMAKE_FIND_ROOT_PATH)
+   foreach(currentFindRoot ${CMAKE_FIND_ROOT_PATH})
+  set(pkgconfigLibDir ${pkgconfigLibDir}:
${currentFindRoot}/usr/lib/pkgconfig:
  ${currentFindRoot}/usr/local/lib/pkgconfig )
+   endforeach(currentFindRoot)
+   set(ENV{PKG_CONFIG_LIBDIR} ${pkgconfigLibDir} )
+   set(ENV{PKG_CONFIG_PATH}  )
+endif(CMAKE_CROSSCOMPILING  AND  CMAKE_FIND_ROOT_PATH)

(and it also messes around with setting a prefix so the directories are 
correct for the host system)

Alex

___
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem