root/simulator/trunk/vendor/cmake/Source/cmPackageConfigureCommand.cpp

Revision 1378, 31.5 kB (checked in by sehenley, 9 months ago)

Documentation.

Line 
1 //    OSRail -- a network enabled railroad operations simulator and utilities
2 //    Copyright (C) 2007,2008 Samuel E. Henley sehenley@comcast.net
3 //
4 //    This program is free software; you can redistribute it and/or modify
5 //    it under the terms of the GNU General Public License as published by
6 //    the Free Software Foundation; either version 2 of the License, or
7 //    (at your option) any later version.
8 //
9 //    This program is distributed in the hope that it will be useful,
10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //    GNU General Public License for more details.
13 //
14 //    You should have received a copy of the GNU General Public License along
15 //    with this program; if not, write to the Free Software Foundation, Inc.,
16 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 //
18
19
20 #include <iostream>
21 #include <fstream>
22 #include <string>
23 #include <cstring>
24 #include <vector>
25 #include <set>
26 #include <map>
27 #include <cstdlib>
28 #include <algorithm>
29 #include <cctype>
30
31 //#include <signal.h>
32
33 #include "cmake.h"
34 #include "cmMakefile.h"
35 #include "cmTest.h"
36
37 #include "cmPackageConfigureCommand.h"
38
39 using namespace std;
40
41 /// \addtogroup utilities "Utilities"
42 /// @{
43 ///   \addtogroup utilitiescmake "Utilities CMake Custom Command PURGECONFIGURE"
44 ///   @{
45
46
47 /// \file
48 /// Special CMake command to filter and unwined the output
49 /// of xxx-config and pkg-config programes.
50 ///
51 /// from cmCacheManager.h in cmake source
52
53 bool cmPackageConfigureCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus &status )
54 {
55     std::string error;
56
57     if( args.empty()  )
58     {
59         SetError( "Error Must have at least a target" );
60         return false;
61     }
62
63     cmTarget* target = Makefile->FindTarget( args[0].c_str() );
64
65     if( !target )
66     {
67         error = "Error unknown target:";
68         error += args[0];
69         SetError( error.c_str() );
70         return false;
71     }
72
73     std::vector< std::string >& argument_list = arguments[args[0]];
74     argument_list.clear();
75
76
77
78     std::string sz;
79     try
80     {
81         for( size_t i=1; i<args.size(); i++ )
82         {
83             if( args[i].empty() )continue; //some are empty
84
85             std::string raw = args[i];
86
87             argument_list.push_back( raw );
88         }
89
90     }
91     catch( ... )
92     {
93         error = "Error reading string:";
94         error += sz;
95         SetError( error.c_str() );
96         return false;
97     }
98
99     return true;
100 }
101
102
103 // static would not work - we are included in command bootstrap cpp file.
104 namespace packageconfigure
105 {
106     //FILE* log_file = 0;
107     //const char* log_file_name = "/home/samuel/working/simulator/branches/dashboard-682/MAKE/bin/packageconfigure/log.txt";
108
109     const char* cmake_flags[] =
110     {
111         "CMAKE_C_FLAGS_",
112         "CMAKE_CXX_FLAGS_"
113     };
114
115  //------------------------------------ convert cmake list to strings ------------------------------------------------
116     /// Convert a cmake string to a vector of strings - can't use cmSystemTools
117     void list2vector( const std::string sz, std::vector< std::string >& vector, bool clear=true )
118     {
119         if( clear )vector.clear();
120
121         size_t start = sz.find_first_not_of(" ;", 0 );
122         while( start != std::string::npos )
123         {
124             std::string name;
125             size_t stop = sz.find_first_of(" ;", start );
126
127             if( stop != std::string::npos )
128             {
129                 vector.push_back( sz.substr( start, stop - start ));
130                 start = sz.find_first_not_of(" ;", stop );
131             }
132             else
133             {
134                 vector.push_back( sz.substr( start, sz.size() ));
135                 start = std::string::npos;
136             }
137         }
138     }
139
140 //------------------------------------ convert cmake list to strings ------------------------------------------------
141     /// Convert a cmake string to a vector of strings - can't use cmSystemTools
142     void list2vector( const std::string sz, std::vector< cmsys::String >& vector, bool clear=true )
143     {
144         if( clear )vector.clear();
145
146         size_t start = sz.find_first_not_of(" ;", 0 );
147         while( start != std::string::npos )
148         {
149             std::string name;
150             size_t stop = sz.find_first_of(" ;", start );
151
152             if( stop != std::string::npos )
153             {
154                 vector.push_back( sz.substr( start, stop - start ));
155                 start = sz.find_first_not_of(" ;", stop );
156             }
157             else
158             {
159                 vector.push_back( sz.substr( start, sz.size() ));
160                 start = std::string::npos;
161             }
162         }
163     }
164 //------------------------------------ convert a set to cmake list ------------------------------------------------
165     /// Convert a set to a simi-colon cmake string
166     void set2list( const std::set< std::string >& set, std::string& result, char sep=';', bool clear=true )
167     {
168         if( clear )result.clear();
169         std::set< std::string >::iterator i = set.begin();
170         while( i != set.end() )
171         {
172             if( !result.empty() )result+= sep;
173             result += *i++;
174         }
175     }
176
177 //------------------------------------ convert cmake list to a set strings ------------------------------------------------
178     /// Convert a cmake string to a set of strings - can't use cmSystemTools
179     void list2set( const std::string sz, std::set< std::string >& set, bool clear=true )
180     {
181         if( clear )set.clear();
182
183         size_t start = sz.find_first_not_of(" ;", 0 );
184         while( start != std::string::npos )
185         {
186             std::string name;
187             size_t stop = sz.find_first_of(" ;", start );
188
189             if( stop != std::string::npos )
190             {
191                 set.insert( sz.substr( start, stop - start ));
192                 start = sz.find_first_not_of(" ;", stop );
193             }
194             else
195             {
196                 set.insert( sz.substr( start, sz.size() ));
197                 start = std::string::npos;
198             }
199         }
200     }
201
202 //------------------------------------ convert vector to cmake list ------------------------------------------------
203     /// Convert a vector to simi-colon cmake string
204     void vector2list( const std::vector< std::string >& vector, std::string& result, bool clear=true )
205     {
206         if( clear )result.clear();
207         for( size_t i=0; i< vector.size(); i++ )
208         {
209             if( !result.empty() )result+= ';';
210             result += vector[i];
211         }
212     }
213
214 //------------------------------------ add a definition to cache - mark it as advance ------------------------------------------------
215     /// Add cache definition
216     static void addCacheDefinition( cmMakefile* makefile, std::vector< std::string >& names, std::vector< std::string >& results, const char* note )
217     {
218         //log_file = fopen( log_file_name, "ab" );
219         //fprintf( log_file, "addCacheDefinition\n" );
220         //fclose( log_file );
221         if( !names.size() )return;
222
223         size_t size = names.size();
224         for( size_t j=0; j<size; j++ )
225         {
226             if( !results[j].empty() )
227             {
228                 std::string symbol;
229                 std::string sz;
230                 sz = "Advanced flag for variable ";
231                 sz += names[j];
232                 symbol = names[j];
233                 symbol += "-ADVANCED";
234                 makefile->AddCacheDefinition( names[j].c_str(), results[j].c_str(), note, cmCacheManager::STRING );
235                 makefile->AddCacheDefinition( symbol.c_str(), "1", sz.c_str(), cmCacheManager::INTERNAL );
236
237             }
238         }
239     }
240
241
242     static char graph( char ch )
243     {
244         if( ch == '\\' )return '/';  //for Windows paths
245         if( std::isgraph( ch ))return ch;
246         return ' ';
247     }
248
249     void saveResult( const char* p, std::set< std::string >& target_build_types, std::map< std::string, std::set< std::string > >& results )
250     {
251         if( p )
252         {
253             std::string raw = p;
254             std::string sz;
255
256             sz.reserve( raw.size() );
257             std::transform( raw.begin(), raw.end(), std::back_inserter( sz ), graph );
258             std::vector< std::string > buffer;
259             list2vector( sz, buffer );
260             for( size_t i=0; i<buffer.size(); i++ )
261             {
262                 sz = buffer[i];
263                 std::set< std::string >::iterator it = target_build_types.begin();
264                 while( it != target_build_types.end() )results[*it++].insert( buffer[i] );
265             }
266         }
267     }
268
269     void saveCFlagResult( const std::string& name, std::set< std::string >& target_build_types, std::map< std::string, std::set< std::string > >& results )
270     {
271         std::vector< std::string > hold;
272         list2vector( name, hold );
273
274         if( target_build_types.empty() )
275         {
276             std::set< std::string > types;
277             types.insert( "RelWithDebInfo" );
278             types.insert( "Release" );
279             types.insert( "MinSizeRel" );
280             for( size_t i=0; i<hold.size(); i++ ) saveResult( hold[i].c_str(), types, results );
281         }
282         else
283         {
284             for( size_t i=0; i<hold.size(); i++ ) saveResult( hold[i].c_str(), target_build_types, results );
285         }
286     }
287
288     void saveLibsResult( const std::string& name, std::set< std::string >& target_build_types, std::map< std::string, std::set< std::string > >& results, bool found_debug )
289     {
290         std::vector< std::string > hold;
291         list2vector( name, hold );
292
293         if( target_build_types.empty() )
294         {
295             std::set< std::string > types;
296             types.insert( "optimized" );
297             if( !found_debug )types.insert( "general" );
298             for( size_t i=0; i<hold.size(); i++ ) saveResult( hold[i].c_str(), types, results );
299         }
300         else
301         {
302             for( size_t i=0; i<hold.size(); i++ ) saveResult( hold[i].c_str(), target_build_types, results );
303         }
304     }
305
306     void mergeCFlags( cmMakefile* makefile, cmTarget* target,
307                       const std::string& build_type_index,
308                       std::string& language,
309                       std::set< std::string >& heap )
310     {
311         //global flags
312         std::set< std::string > global_flags;
313         std::string global = "CMAKE_";
314         global += language;
315         global += "_FLAGS";
316         const char* p = makefile->GetDefinition( global.c_str() );
317         if( p )list2set( p, global_flags );
318
319         std::set< std::string > build_flags;
320         std::string build = "CMAKE_";
321         build += language;
322         build += "_FLAGS_";
323         build += cmSystemTools::UpperCase( build_type_index );
324         p = makefile->GetDefinition( build.c_str() );
325         if( p )list2set( p, build_flags );
326
327         std::set< std::string > local_flags;
328         std::string local;
329         switch( target->GetType() )
330         {
331         case cmTarget::STATIC_LIBRARY : local = "CMAKE_STATIC_"; break;
332         case cmTarget::SHARED_LIBRARY : local = "CMAKE_SHARED_LIBRARY_"; break;
333         case cmTarget::MODULE_LIBRARY : local = "CMAKE_SHARED_MODULE_"; break;
334         case cmTarget::EXECUTABLE :
335         default:
336             break;
337         }
338
339         if( !local.empty() )
340         {
341             local += language;
342             local += "_FLAGS";
343             p = makefile->GetDefinition( local.c_str() );
344             if( p )list2set( p, local_flags );
345         }
346
347         //look for cflags
348         std::set< std::string > compiler_flags;
349         p = target->GetProperty( "COMPILE_FLAGS" );
350         if( p )list2set( p, compiler_flags );
351         std::set< std::string >::iterator it = heap.begin();
352         while( it != heap.end() )
353         {
354             //cflags only ones remaining
355             std::set< std::string >::iterator ix = it;
356             std::string line = *it++;
357             size_t count = std::count( global_flags.begin(), global_flags.end(), line );
358             count += std::count( build_flags.begin(), build_flags.end(), line );
359             count += std::count( local_flags.begin(), local_flags.end(), line );
360             count += std::count( compiler_flags.begin(), compiler_flags.end(), line );
361             if( !count )
362             {
363                 build_flags.insert( line );
364             }
365             heap.erase( ix );
366
367         }
368         std::string result;
369         set2list( build_flags, result, ' ' );
370         makefile->AddDefinition( build.c_str(), result.c_str() );
371
372     }
373
374
375     void mergeLibrarySearchPaths( cmMakefile* makefile, cmTarget* target,
376                                   const std::string& build_type_index,
377                                   std::set< std::string >& heap )
378     {
379         const std::vector< std::string >& includes = target->GetLinkDirectories();
380
381         std::set< std::string >::iterator it = heap.begin();
382         while( it != heap.end() )
383         {
384
385             std::set< std::string >::iterator ix = it;
386             std::string line = *it++;
387             if( line.find( "-L" ) == 0 )
388             {
389                 std::string sz = line.substr( 2, line.size() );
390                 if( std::count( includes.begin(), includes.end(), sz ) == 0 )
391                 {
392                     target->AddLinkDirectory( sz.c_str() );
393                 }
394                 heap.erase( ix );
395             }
396         }
397
398     }
399
400     struct Package
401     {
402         cmTarget::LinkLibraryType type;
403         std::string               name;
404     };
405
406     bool operator==( const cmTarget::LibraryID& a, const Package& b )
407     {
408         if( b.name != a.first )return false;
409         if( b.type != a.second )return false;
410         return true;
411     }
412
413     void mergeLibraries( cmMakefile* makefile, cmTarget* target,
414                          const std::string& build_type_index,
415                          std::set< std::string >& heap )
416     {
417         Package library;
418
419         if( build_type_index == "debug" )library.type = cmTarget::DEBUG;
420         else if( build_type_index == "optimized" )library.type = cmTarget::OPTIMIZED;
421         else library.type = cmTarget::GENERAL;
422
423
424         const cmTarget::LinkLibraryVectorType& libraries = target->GetLinkLibraries();
425
426         std::set< std::string >::iterator it = heap.begin();
427         while( it != heap.end() )
428         {
429              std::set< std::string >::iterator ix = it;
430              std::string line = *it++;
431              if( line.find( "-l" ) == 0 )
432              {
433                  library.name = line.substr( 2, line.size() );
434                  if( std::count( libraries.begin(), libraries.end(), library ) == 0 )
435                  {
436                      target->AddLinkLibrary( *makefile, target->GetName(), library.name.c_str(), library.type );
437                      //if( strcmp( target->GetName(), "Simulator" ) == 0
438                      //    && library.type == cmTarget::DEBUG ) cout << library.name << endl;
439                  }
440                  heap.erase( ix );
441              }
442         }
443
444     }
445
446     void mergeCompilerSearchPaths( cmMakefile* makefile, cmTarget* target,
447                                    const std::string& build_type_index,
448                                    std::set< std::string >& heap )
449     {
450         std::vector< std::string >& includes = makefile->GetIncludeDirectories();
451
452         std::set< std::string >::iterator it = heap.begin();
453         while( it != heap.end() )
454         {
455
456             std::set< std::string >::iterator ix = it;
457             std::string line = *it++;
458             if( line.find( "-I" ) == 0 )
459             {
460                 std::string sz = line.substr( 2, line.size() );
461                 if( std::count( includes.begin(), includes.end(), sz ) == 0 )
462                 {
463                     includes.push_back( sz );
464                 }
465                 heap.erase( ix );
466             }
467             makefile->SetIncludeDirectories( includes );
468         }
469
470     }
471
472     void mergeDefinitions( cmMakefile* makefile, cmTarget* target,
473                            const std::string& build_type_index,
474                            bool current_build,
475                            std::set< std::string >& heap )
476     {
477         std::set< std::string > global_defines;
478         std::string symbol = "COMPILE_DEFINITIONS";
479         const char* p = makefile->GetProperty( symbol.c_str(), cmProperty::DIRECTORY );
480         if( p ) list2set( p, global_defines, false );
481         p = target->GetProperty( symbol.c_str(), cmProperty::TARGET );
482         if( p ) list2set( p, global_defines, false );
483         symbol += '_';
484         symbol +=  cmSystemTools::UpperCase( build_type_index );
485         std::set< std::string > build_defines;
486         p = makefile->GetProperty( symbol.c_str(), cmProperty::DIRECTORY );
487         if( p ) list2set( p, build_defines, false );
488         p = target->GetProperty( symbol.c_str(), cmProperty::TARGET );
489         if( p ) list2set( p, build_defines, false );
490
491         std::set< std::string > defines;
492         std::set< std::string >::iterator it = heap.begin();
493         while( it != heap.end() )
494         {
495              std::set< std::string >::iterator ix = it;
496              std::string line = *it++;
497              if( line.find( "-D" ) == 0 )
498              {
499                  std::string look = line.substr( 2, line.size());
500                  size_t count = std::count( global_defines.begin(), global_defines.end(), look );
501                  count += std::count( build_defines.begin(), build_defines.end(), look );
502                  if( !count )
503                  {
504                      defines.insert( look );
505                  }
506
507                  heap.erase( ix );
508              }
509
510
511         }
512
513         if( !defines.empty() )
514         {
515             std::set< std::string >::iterator x = defines.begin();
516             while( x != defines.end() )
517             {
518                 std::string sz = (*x);
519                 target->AppendProperty( symbol.c_str(), (*x).c_str() );
520                 if( current_build )
521                 {
522                     makefile->AppendProperty( "COMPILE_DEFINITIONS", (*x).c_str() );
523                 }
524                 x++;
525             }
526         }
527     }
528
529     struct Returns
530     {
531         std::string buffer;
532         int         return_value;
533         bool        exit_value;
534     };
535
536     static std::map< std::string, Returns > command_cache;
537
538     bool doCommand( std::string& line, std::string* buffer, int* return_value, std::string& working_directory )
539     {
540         std::string key = line + working_directory;
541         Returns& x = command_cache[key];
542         if( !x.buffer.empty() )
543         {
544             *buffer = x.buffer;
545             *return_value = x.return_value;
546         }
547         else
548         {
549
550             std::vector< cmsys::String > command;
551             list2vector( line, command );
552             x.exit_value = cmSystemTools::RunSingleCommand( command, buffer, return_value, working_directory.c_str(), false, 0.0 );
553             x.buffer = *buffer;
554             x.return_value = *return_value;
555         }
556
557         return x.exit_value;
558     }
559
560
561     //------------------------------------ get a property target, global order ------------------------------------------------
562     /// Get a property - in target, then directory, then global - order.
563     const char* getProperty( cmMakefile* mf, const cmTarget* target, const char* property )
564     {
565         const char* p = const_cast<cmTarget*>(target)->GetProperty( property, cmProperty::TARGET );
566         if( !p ) p = mf->GetProperty( property, cmProperty::DIRECTORY );
567         // I would work up the chain of makefiles but codeblocks dosn't have sub-projects.
568         if( !p ) p = mf->GetCMakeInstance()->GetProperty( property, cmProperty::GLOBAL );
569
570         return p;
571     }
572
573
574
575 }  //namespace packageconfigure
576
577
578 void cmPackageConfigureCommand::FinalPass()
579 {
580         //log_file = fopen( log_file_name, "ab" );
581         //fprintf( log_file, "finalPass\n" );
582         //fclose( log_file );
583     std::map< std::string, std::vector< std::string > >::iterator targets = arguments.begin();
584     while( targets != arguments.end() )
585     {
586         std::vector< std::string >& argument_list = (*targets).second;
587
588         //cout << (*targets).first << endl;
589
590         std::string raw;
591         const char* p = Makefile->GetDefinition( "CMAKE_CONFIGURATION_TYPES" );
592         if( !p )raw = "RelWithDebInfo";
593         else raw = p;
594
595         std::vector< std::string > build_types;
596         packageconfigure::list2vector( raw, build_types );
597         build_types.push_back( std::string( "debug" ) ); //library types
598         build_types.push_back( std::string( "optimized" ) ); //library types
599         build_types.push_back( std::string( "general" ) ); //library types
600         // Type builds with a set of results
601         std::map< std::string, std::set< std::string > >results;
602         for( size_t j=0; j<build_types.size(); j++ )
603             results.insert( std::pair< std::string, std::set< std::string > >
604                 ( build_types[j], std::set< std::string >() ) );
605
606         std::string command;
607         std::string working_directory = Makefile->GetStartDirectory();
608         std::string output;
609         std::string buffer;
610         int return_value;
611
612        // for each argument
613         std::vector< std::string >::iterator it = argument_list.begin();
614         // set the target_build_types to the default build type
615         std::set< std::string > target_build_types;
616         target_build_types.clear();
617
618         // the target
619         cmTarget* target = Makefile->FindTarget( (*targets).first.c_str() );
620         if( !target ) continue;
621
622         // search paths for pc and config files
623         /// \note PackageConfigure CMake Global, Directory and Target Property PACKAGECONFIGURE_PC_FILES
624         /// sets the location of a working directory for pkg-config utility pc files. This is used for
625         /// files that override or augment the /usr/... /lib/pkgconfig directory files.
626         /// If ARCHIVE_OUTPUT_DIRECTORY is set - set to ARCHIVE_OUTPUT_DIRECTORY/pkgconfig,
627         /// if not then LIBRARY_OUTPUT_DIRECTORY/pkgconfig.
628         /// if not then LIBRARY_OUTPUT_PATH/pkgconfig.
629         /// or defaults to CMAKE_BINARY_DIR/pkgconfig.
630         /// If the pkgconfig directory is found pkg-config will use the system directory if it doesn't
631         /// find the pc file, it's the current directory.
632         std::string pc_search_path;
633         p = packageconfigure::getProperty( Makefile, target, "PACKAGECONFIGURE_PC_FILES" );
634         if( p )pc_search_path = p;
635         else
636         {
637             if( !p )
638             {
639                 p = packageconfigure::getProperty( Makefile, target, "ARCHIVE_OUTPUT_DIRECTORY" );
640             }
641             if( p ) pc_search_path = p;
642             if( !p )
643             {
644                 p = packageconfigure::getProperty( Makefile, target, "LIBRARY_OUTPUT_DIRECTORY" );
645             }
646             if( p ) pc_search_path = p;
647             if( !p )
648             {
649                 p = Makefile->GetDefinition( "LIBRARY_OUTPUT_PATH" );
650             }
651             if( p ) pc_search_path = p;
652             if( !p  )
653             {
654                 pc_search_path = Makefile->GetStartOutputDirectory();
655             }
656             pc_search_path += "/pkgconfig/";
657         }
658
659
660         /// \note PackageConfigure CMake Global, Directory and Target Property PACKAGECONFIGURE_XXX-CONFIG_FILES
661         /// sets the location of a working directory for xxx-config scripts. This is used for
662         /// files that replace, override or augment the /usr/... /bin scripts.
663         /// If set defaults to EXECUTABLE_OUTPUT_PATH - else CMAKE_BINARY_DIR
664
665         std::string xxx_config_search_path;
666         p = packageconfigure::getProperty( Makefile, target, "PACKAGECONFIGURE_XXX-CONFIG_FILES" );
667         if( p )xxx_config_search_path = p;
668         else
669         {
670             p = Makefile->GetDefinition( "EXECUTABLE_OUTPUT_PATH" );
671             if( p ) xxx_config_search_path = p;
672             else xxx_config_search_path = Makefile->GetStartOutputDirectory();
673         }
674
675         while( it != argument_list.end() )
676         {
677
678             std::string param = *it++;
679
680             if( std::count( build_types.begin(), build_types.end(), param ) == 0 )
681             {
682                 std::string command;
683
684                 if( param.find( "-config" ) != std::string::npos )
685                 {
686                     command.clear();
687                     command = "./";
688                     command += param;
689                     std::vector< std::string >::iterator cmd = it;
690                     while( cmd != argument_list.end() )
691                     {
692                         param = *cmd;
693                         if( std::count( build_types.begin(), build_types.end(), param ) != 0 )break; //stop on a new build type
694                         if( param.find( "--" ) == std::string::npos )break; //xxx-config only have switches
695                         if( param.find( "-config" ) != std::string::npos )break; //stop on a new xxx-config command
696                         command += ' ';
697                         command += param;
698                         cmd++;
699                     }
700                     it = cmd; //next
701
702
703
704                     //Will not work under windows symbols not exported to dll - normally
705                     if( packageconfigure::doCommand( command, &buffer, &return_value, xxx_config_search_path ))
706                     {
707                         packageconfigure::saveResult( buffer.c_str(), target_build_types, results );
708                     }
709                     else
710                     {
711                         //system wide
712                         command.erase( 0, 2 );
713                         if( packageconfigure::doCommand( command, &buffer, &return_value, xxx_config_search_path ))
714                         {
715                             packageconfigure::saveResult( buffer.c_str(), target_build_types, results );
716                         }
717                     }
718                     target_build_types.clear();
719                 }
720                 else
721                 {
722                     bool found_debug = false;
723                     //No target type (Debug, Release, etc)
724                     //So defult to a debug .pc file
725                     if( target_build_types.empty() )
726                     {
727                         std::string pc_file = param;
728                         target_build_types.clear();
729                         target_build_types.insert( "Debug" );
730                         size_t ix = pc_file.rfind( ".pc" );
731                         if( ix != std::string::npos )pc_file.insert( ix, "_debug" );
732                         else pc_file += "_debug";
733
734                         command = "pkg-config --cflags ";
735                         command += pc_file;
736
737                         //cout << command;
738
739                         if( packageconfigure::doCommand( command, &buffer, &return_value, pc_search_path )
740                             && !return_value )
741                         {
742                             packageconfigure::saveCFlagResult( buffer, target_build_types, results );
743                             //cout << buffer << endl;
744                         }
745                         // No xxx_debug.pc file goto system directory for flags
746                         else
747                         {
748                             command.clear();
749
750                             command = "pkg-config --cflags ";
751                             command += param;
752                             if( packageconfigure::doCommand( command, &buffer, &return_value, working_directory )
753                                 && !return_value )
754                             {
755                                  packageconfigure::saveCFlagResult( buffer, target_build_types, results );
756                             }
757                         }
758
759                         // Do the above but for libraries
760                         target_build_types.clear();
761                         target_build_types.insert( "debug" );
762
763                         command.clear();
764
765                         command = "pkg-config --libs ";
766                         command += pc_file;  //constructed with xxx_debug.pc
767                         //cout << command;
768                         if( packageconfigure::doCommand( command, &buffer, &return_value, pc_search_path )
769                             && !return_value )
770                         {
771                             packageconfigure::saveLibsResult( buffer, target_build_types, results, found_debug );
772                             found_debug = true;
773                             //cout << buffer << endl;
774                         }
775                         // No xxx_debug.pc file goto system directory for flags
776                         else
777                         {
778                             command.clear();
779
780                             command = "pkg-config --libs ";
781                             command += param;
782                             if( packageconfigure::doCommand( command, &buffer, &return_value, working_directory )
783                                 && !return_value )
784                             {
785                                  packageconfigure::saveLibsResult( buffer, target_build_types, results, found_debug );
786                             }
787                         }
788
789                         target_build_types.clear();
790                     }
791
792                     command.clear();
793                     command = "pkg-config --cflags ";
794                     command += param;
795
796                     std::string buffer;
797                     int return_value;
798                     if( packageconfigure::doCommand( command, &buffer, &return_value, pc_search_path )
799                         && !return_value )
800                     {
801                         packageconfigure::saveCFlagResult( buffer, target_build_types, results );
802                     }
803
804                     command.clear();
805
806                     command = "pkg-config --libs ";
807                     command += param;
808
809                     if( packageconfigure::doCommand( command, &buffer, &return_value, pc_search_path )
810                         && !return_value )
811                     {
812                         packageconfigure::saveLibsResult( buffer, target_build_types, results, found_debug );
813                     }
814                 }
815             }
816             else
817             {
818                 target_build_types.insert( param ); //new target_build_types
819             }
820
821         }
822
823
824         std::string current_build_type;
825         p = Makefile->GetDefinition( "CMAKE_BUILD_TYPE" );
826         if( p ) current_build_type = p;
827
828         //Do each build
829         for( size_t build_type_index=0; build_type_index < build_types.size(); build_type_index++ )
830         {
831             std::string build = build_types[build_type_index];
832             std::string build_name = build;
833
834             std::set< std::string >& heap = results[build];
835             bool current_build = false;
836             if( !current_build_type.empty() )
837             {
838                 if( build == current_build_type )current_build = true;
839                 else
840                 {
841                     if( current_build_type == "Debug" && build == "debug" )current_build = true;
842                     else if( current_build_type != "Debug" && build == "optimized" )current_build = true;
843                     else if( build == "general" )current_build = true;
844                 }
845
846             }
847
848             //flags in this build
849             packageconfigure::mergeDefinitions( Makefile, target, build_name, current_build, heap );
850             packageconfigure::mergeCompilerSearchPaths( Makefile, target, build_name, heap );
851             packageconfigure::mergeLibrarySearchPaths( Makefile, target, build_name, heap );
852             packageconfigure::mergeLibraries( Makefile, target, build_name, heap );
853
854             std::set< cmStdString > languages;
855             target->GetLanguages( languages );
856
857             std::set< cmStdString >::iterator it = languages.begin();
858
859
860             while( it != languages.end() )
861             {
862                 std::string language = *it++;
863
864                 packageconfigure::mergeCFlags( Makefile, target, build_name, language, heap );
865
866             }
867
868
869         }
870
871         targets++;
872
873     }
874     arguments.clear();
875
876 }
877
878
879
880
881
882 ///   @}   group utilitiescmake
883 /// @}   group utilities
Note: See TracBrowser for help on using the browser.