Skip to content
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

Fix for linking different archs #2

Open
wants to merge 657 commits into
base: master
Choose a base branch
from
Open

Fix for linking different archs #2

wants to merge 657 commits into from

Conversation

jkp
Copy link

@jkp jkp commented Jan 30, 2012

Hi there

I was looking at trying out Ninja build with our rather large CMake C++ project but I hit a hurdle early on. We force the architecture to i386 even on x86_64 platforms and the targets the Ninja generator spat out seemed to choke when linking.

This is a patch which seems to fix that. I arrived at this by looking at the link rule for CXX (in Modules/CMakeCXXInformation.cmake)

<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>

Although you look up the architecture flags in cmNinjaNormalTargetGenerator::WriteLinkRule, they are only included in the build rule if it references <LANGUAGE_COMPILE_FLAGS> (which this rule doesn't).

I used the code in the makefile generator as a reference - in there they store them in FLAGS and they are picked up from there.

kwrobot and others added 30 commits October 6, 2011 00:05
Commit 8a0eb78 (Constify many getters of cmGlobalGenerator, 2011-03-26)
added const qualifiers to many cmGlobalGenerator methods.  Fix the
signature of the virtual function overrides in cmGlobalXCodeGenerator to
match.
Commit 8a0eb78 (Constify many getters of cmGlobalGenerator, 2011-03-26)
added const qualifiers to many cmGlobalGenerator methods but left the
resulting lines beyond our style's limit of 79 characters.
648c454 Add features from KDE for arguments to qdbusxml2cpp.
b0cd630 Refactor find_* command final path list computation
3df49dc fix #12392: handle CMAKE_CXX_COMPILER_ARG1 for Eclipse projects
41719b7 libarchive: fix typo in CheckFileOffsetBits.cmake
240d39a Fix XML safety issue with adding preprocessor defines in CodeBlocks project.
e36a1be fix #12262: use the C dependency scanner also for ASM files
08271ec Build each library only once instead of once for each test.
c83cfd7 Remove unused define.
32f8437 Fix line-too-long style violations
029ab31 Constify XCode generator getters to match cmGlobalGenerator
fec4b63 Fix configuration-dependent flag lookup in cmLocalGenerator::GetTargetFlags
557956f Introduce a cmGlobalGenerator::ResolveLanguageCompiler function
5b114c9 Introduce a cmLocalGenerator::ConvertToIncludeReference function
903d914 Make cmLocalGenerator::ConvertToLinkReference virtual
8a0eb78 Constify many getters of cmGlobalGenerator.
4532d36 Add const versions of some getters.
3db2973 Refactor TargetTypeNames.
BSD make doesn't use -v for printing its name and version, and so
complains on stderr that this is a bad command line option, used
in Tests/FindPackageModeMakefileTest/CMakeLists.txt .
Silence stderr to make that ugly output go away.
Patch by David Coppy.

Alex
The ruby library on OpenBSD is named rubyXY, not ruby X.y.
Find that too.

Alex
Avoiding dereference of NULL pointers is always good.
Try to detect the eclipse version and put it in the cache.

Alex
pcc and others added 29 commits November 8, 2011 15:35
…excluded from all

Now we respect the EXCLUDE_FROM_ALL property on directories.
This test specifically checks that we output build system files in
each directory, by running the test in a subdirectory of the build
directory.  Since the Ninja generator deliberately does not do this,
run the test from the root build directory for Ninja only.
by reducing the length of the paths it generates.
… utilities

This helps filter out non-existent utilities (I'm looking at you,
path64) and is more reliable for depending on an EXECUTABLE (etc.)
"utility".
Each target has an alias for its name as well as the basename of the
main file created.  If an ambiguity arises then no alias is created
at all.
(CMAKE_DEPFILE_FLAGS_${lang}), instead of hardcoding them.

At the same time, fix the BuildDepends test by providing a way to
force dependency tracking.
@pcc
Copy link
Owner

pcc commented Jan 30, 2012

On Mon, Jan 30, 2012 at 06:55:36AM -0800, Jamie Kirkpatrick wrote:

Hi there

I was looking at trying out Ninja build with our rather large CMake C++ project but I hit a hurdle early on. We force the architecture to i386 even on x86_64 platforms and the targets the Ninja generator spat out seemed to choke when linking.

This is a patch which seems to fix that. I arrived at this by looking at the link rule for CXX (in Modules/CMakeCXXInformation.cmake)

<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>

Although you look up the architecture flags in cmNinjaNormalTargetGenerator::WriteLinkRule, they are only included in the build rule if it references <LANGUAGE_COMPILE_FLAGS> (which this rule doesn't).

I used the code in the makefile generator as a reference - in there they store them in FLAGS and they are picked up from there.

The latest version of the code is in the ninja-generator-pr branch,
and this architecture flag issue was "fixed" while I was working on the
Mac OS X port. If you look at both cmMakefileExecutableTargetGenerator
and cmMakefileLibraryTargetGenerator you will notice that Executable
adds the architecture flags to FLAGS and Library adds them to
LANGUAGE_COMPILE_FLAGS. This looks a lot like a mistake made when
duplicating code between Executable and Library. (Of course, in
my generator I avoid any such nonsense by combining Executable and
Library into a single module).

Rather than trying to fix this in the makefile generator and the
modules (at the risk of breaking something) I decided to mimic this
behaviour in my generator, for better or worse. Below are the changes
that I made (which are now rolled up into the ninja-generator-pr
branch):

diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index c3894ae..7bfdd46 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -117,6 +117,7 @@ void
 cmNinjaNormalTargetGenerator
 ::WriteLinkRule()
 {
+  cmTarget::TargetType targetType = this->GetTarget()->GetType();
   std::string ruleName = this->LanguageLinkerRule();

   if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
@@ -161,7 +162,8 @@ cmNinjaNormalTargetGenerator
     this->GetLocalGenerator()->AddLanguageFlags(langFlags,
                                                 this->TargetLinkLanguage,
                                                 this->GetConfigName());
-    langFlags += "$ARCHITECTURE_FLAGS";
+    if (targetType != cmTarget::EXECUTABLE)
+      langFlags += " $ARCH_FLAGS";
     vars.LanguageCompileFlags = langFlags.c_str();

     // Rule for linking library.
@@ -193,7 +195,7 @@ cmNinjaNormalTargetGenerator
   if (this->TargetNameOut != this->TargetNameReal) {
     std::string cmakeCommand =
       this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND");
-    if (this->GetTarget()->GetType() == cmTarget::EXECUTABLE)
+    if (targetType == cmTarget::EXECUTABLE)
       this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_EXECUTABLE",
                                           cmakeCommand +
                                           " -E cmake_symlink_executable"
@@ -283,11 +285,13 @@ cmNinjaNormalTargetGenerator

 void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 {
+  cmTarget::TargetType targetType = this->GetTarget()->GetType();
+
   // Write comments.
   cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
   this->GetBuildFileStream()
     << "# Link build statements for "
-    << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+    << cmTarget::GetTargetTypeName(targetType)
     << " target "
     << this->GetTargetName()
     << "\n\n";
@@ -320,14 +324,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                                             vars["LINK_FLAGS"],
                                             *this->GetTarget());

-  // Compute specific link flags.
-  this->GetLocalGenerator()->AddArchitectureFlags(vars["ARCHITECTURE_FLAGS"],
-                                                  this->GetTarget(),
-                                                  this->TargetLinkLanguage,
-                                                  this->GetConfigName());
+  // Compute architecture specific link flags.  Yes, these go into a different
+  // variable for executables, probably due to a mistake made when duplicating
+  // code between the Makefile executable and library generators.
+  this->GetLocalGenerator()
+      ->AddArchitectureFlags(targetType == cmTarget::EXECUTABLE
+                               ? vars["FLAGS"]
+                               : vars["ARCH_FLAGS"],
+                             this->GetTarget(),
+                             this->TargetLinkLanguage,
+                             this->GetConfigName());
   vars["SONAME"] = this->TargetNameSO;

-  if (this->GetTarget()->GetType() == cmTarget::SHARED_LIBRARY) {
+  if (targetType == cmTarget::SHARED_LIBRARY) {
     std::string install_name_dir =
       this->GetTarget()->GetInstallNameDirForBuildTree(this->GetConfigName());

@@ -391,7 +400,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                                      vars);

   if (targetOutput != targetOutputReal) {
-    if (this->GetTarget()->GetType() == cmTarget::EXECUTABLE) {
+    if (targetType == cmTarget::EXECUTABLE) {
       cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
                                   "Create executable symlink " + targetOutput,
                                          "CMAKE_SYMLINK_EXECUTABLE",

Thanks,

Peter

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

Successfully merging this pull request may close these issues.