Solved

conditional output in makefile

Posted on 2008-10-20
23
373 Views
Last Modified: 2013-12-16
Hi All,

I have the following code in my config.h

#define SERVER_MODE 1


Then I want the make file to test for this value in order to generate the output


Sthg like that :

Ifeq (SERVER_MODE,1)
à my outout is server
Else
My output is client

Endif


Can you help to get the right syntax

Im running my code on Sun 5.10
0
Comment
Question by:bachra04
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 9
  • 5
23 Comments
 
LVL 2

Author Comment

by:bachra04
ID: 22760109
This is an urgent question
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760199
Usually, you'd define the SERVER_MODE in the makefile, and pass it to the compiler using -DSERVER_MODE=1
0
 
LVL 2

Author Comment

by:bachra04
ID: 22760260
The problem is that I use SERVER_MODE inside my main.cpp class
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22760278
You could do something like:

!if "$(CFG)" == "SERVER"
#statements for server build

!endif

!if "$(CFG)" == "CLIENT"
#statements for client build

!endif

Then pass the configuration when calling make (nmake at windows) by adding  CFG=SERVER to the call.


0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760297
>> The problem is that I use SERVER_MODE inside my main.cpp class

That's ok. By passing the define using -DSERVER_MODE=1, it will be available in the main.cpp file. It would be as if you defined it in the file itself.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22760334
To read the SERVER_MODE from header file you could use a grep (or find at Windows) and depending on the result call make with client or server option.
0
 
LVL 2

Author Comment

by:bachra04
ID: 22760420
>>That's ok. By passing the define using -DSERVER_MODE=1, it will be available in the main.cpp file. It would be as if you defined it in the file itself.

Is it possible to write code inside the Make file so I extract the value of SERVER_MODE by simply including config.h inside my makefile ?

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760462
>> Is it possible to write code inside the Make file so I extract the value of SERVER_MODE by simply including config.h inside my makefile ?

That's the reverse world. The makefile defines what kind of application you build. The config.h file should be used for more general configuration settings (general to both client and server).

A simple example makefile (just to illustrate what I mean) is below. It is either called like :

        make server

or :

        make client

depending on which you want to build.
## makefile ##
 
server : main.cpp
	CC -DSERVER_MODE=1 main.cpp -o server
 
client : main.cpp
	CC -DSERVER_MODE=0 main.cpp -o client

Open in new window

0
 
LVL 2

Author Comment

by:bachra04
ID: 22760544
I agree with you but we have a building framework and I only have the right to change the makefile inside my directory (I don't have direct access to gcc options)



#OBJ_DIR = ./$(SRV_BUILD)/$(COMPILER)

#ADD_FLAGS = -I. -I..

#include ../common.mk

#include ./files.mk

#include ./CProtocolConfig.h


#SHARED_LIB = $(LIB_DIR)/libProtocols-$(LIBSSUFF)

#all:  $(SHARED_LIB)

#clean: clean_sharedls

#clobber: clobber_shared
      
#include ../common_targets.mk

#-include $(DEP_FILES)


OBJ_DIR = ./$(SRV_BUILD)/$(COMPILER)

BIN_DIR = ./bin/$(SRV_BUILD)/$(COMPILER)

ADD_FLAGS = -I. -I..
include ../common.mk

include ./files.mk

#ifeq(SERVER_MODE, 1)
#GWSRV = $(BIN_DIR)/QmtfServer
#else
GWSRV = $(BIN_DIR)/QmtfClient
#endif

SOL_COMMON = -lCommon-$(LIBSUFF)
#SOL_DBACC =  -lDBAccess-$(LIBSUFF)
#SOL_PROTO =  -lProtocols-$(LIBSUFF)
#SOL_FIX = -lFix-$(LIBSUFF)
SOLIBS = -L$(LIB_DIR) $(SOL_COMMON)

all:  $(GWSRV)

$(GWSRV) : $(BIN_DIR) $(OBJ_DIR) $(ARLIBS) $(OBJ_FILES)
      $(CCC) $(COMMON_EXEC) $(OBJ_FILES) $(ARLIBS) $(EXEC_FLAGS) $(BOOST_LINK) $(SOLIBS) -o $(GWSRV)
      
clean:
      rm -f $(GWSRV) $(OBJ_FILES) $(DEP_FILES)
      
clobber:
      rm -rf $(OBJ_DIR) $(BIN_DIR)
      
include ../common_targets.mk

-include $(DEP_FILES)

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22760580
>>>> That's the reverse world.
Infinity is right. A header is a bad place to store build options. You would need to change the header when building both client and server at one system. Or, if using a version and configuration system to manage sources between systems, you would need to have different active versions of the same header.

Better pass the SERVER_MODE as compiler option as Infinity explained in his first comment.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760620
>> I don't have direct access to gcc options)

The gcc options are passed in the makefile. So, you just have to modify the makefile. See my example.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22760653
>>>> I only have the right to change the makefile inside my directory

Then, you either should provide 2 makefiles where one was building the client and another builds the server or you build both the client and the server in the makefile.  


>>> (I don't have direct access to gcc options)
You have. Add the -DSERVER_MODE=1 to the statement beginning with $(CCC)
0
 
LVL 2

Author Comment

by:bachra04
ID: 22760724
You're right

I can do that but if you see I want my output name once called qmtfServer and another time called QmtfClient based on the value of only one variable

#GWSRV = $(BIN_DIR)/QmtfServer
#else
GWSRV = $(BIN_DIR)/QmtfClient
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760729
How about :
OBJ_DIR = ./$(SRV_BUILD)/$(COMPILER)
 
BIN_DIR = ./bin/$(SRV_BUILD)/$(COMPILER)
 
ADD_FLAGS = -I. -I..
include ../common.mk
 
include ./files.mk
 
SERVER_BIN = $(BIN_DIR)/QmtfServer
CLIENT_BIN = $(BIN_DIR)/QmtfClient
 
SOL_COMMON = -lCommon-$(LIBSUFF)
#SOL_DBACC =  -lDBAccess-$(LIBSUFF)
#SOL_PROTO =  -lProtocols-$(LIBSUFF)
#SOL_FIX = -lFix-$(LIBSUFF)
SOLIBS = -L$(LIB_DIR) $(SOL_COMMON)
 
all : server client
 
server : $(SERVER_BIN)
 
client : $(CLIENT_BIN)
 
$(SERVER_BIN) : $(BIN_DIR) $(OBJ_DIR) $(ARLIBS) $(OBJ_FILES)
	$(CCC) -DSERVER_MODE=1 $(COMMON_EXEC) $(OBJ_FILES) $(ARLIBS) $(EXEC_FLAGS) $(BOOST_LINK) $(SOLIBS) -o $(SERVER_BIN)
 
$(CLIENT_BIN) : $(BIN_DIR) $(OBJ_DIR) $(ARLIBS) $(OBJ_FILES)
	$(CCC) -DSERVER_MODE=0 $(COMMON_EXEC) $(OBJ_FILES) $(ARLIBS) $(EXEC_FLAGS) $(BOOST_LINK) $(SOLIBS) -o $(CLIENT_BIN)
      
clean:
	rm -f $(SERVER_BIN) $(CLIENT_BIN) $(OBJ_FILES) $(DEP_FILES)
      
clobber:
	rm -rf $(OBJ_DIR) $(BIN_DIR)
      
include ../common_targets.mk
 
-include $(DEP_FILES)

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760736
If you want to build the server, you call :

        make server

If you want to build the client :

        make client


Couldn't be simpler ;)
0
 
LVL 2

Author Comment

by:bachra04
ID: 22760940
No couldn't be simpler
but inside my main class how to test the SERVER_MODE value ?
using #if ?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22760946
>> but inside my main class how to test the SERVER_MODE value ?

The same way you are doing now :) Just treat it as if it was #define'd.


>> using #if ?

For example, yes.
0
 
LVL 2

Author Comment

by:bachra04
ID: 22761103
I got the client and server output. but only the name is changing. looks like it does not take the SERVER_MODE value
#if SERVER_MODE returns usually false
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22761327
>> returns usually false

What do you mean by "usually" ?


>> looks like it does not take the SERVER_MODE value

Can you show your source code ? Did you use the makefile I posted ? Did you remove the #define from config.h ?
0
 
LVL 2

Author Comment

by:bachra04
ID: 22761350
yes I have remove the
#define from config.h ?

#if SERVER_MODE

    if (argc < 3)
    {
      std::cerr << "Usage: QmtfServer <host> <port> \n";
      return 1;
            }

            ORBIXA_PREPARE_COMM_SESSION      
            CProtocolInfo cInfo(ORBIXA_IO_COMM);
            
            cInfo.setHostAddress(argv[1]);
            cInfo.setHostPort(boost::lexical_cast<unsigned int>(argv[2]));
            cInfo.setProtocol(IProtocolInfo::eTCP_IP);
            cInfo.setMode(IProtocolInfo::eServer);
            cInfo.setChannelNumber(1);

            IInternalProtocol* pInternalProtocol =
                  CInternalProtocolFactory::getInstance()->getInternalProtocol(&cInfo);

            IInternalProtocol::protocols pvecMeProtocol;
            pInternalProtocol->getProcessProtocol(IInternalProtocol::PROC_ME, pvecMeProtocol);

            // Set and hook the handler      
            pvecMeProtocol[0]->setProtocolHandler<CMyProtocolHandler>();
            pvecMeProtocol[0]->hookHandlers();

            ORBIXA_START_COMM_SESSION            

            char line[qmtf_message::max_body_length + 1];            
            while (std::cin.getline(line, qmtf_message::max_body_length + 1))
            {
                   using namespace std; // For strlen and memcpy.
                   qmtf_message msg;
                   msg.setType(7);
                   msg.body_length(strlen(line));
                   memcpy(msg.body(), line, msg.body_length());
                   msg.encode_header();                   
                   pvecMeProtocol[0]->writeQueue( 0, 7, msg.body_./length(), (const void*) msg.body());
            }

            ORBIXA_END_COMM_SESSION
                  
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }
      
#else

            //==============================
            //
            //      Create a      TCP client
            //
            //==============================


            if (argc != 3)
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 500 total points
ID: 22761378
That's a big #if. Are you sure you don't just want to place the server and client code in separate source files ? That would make things a bit nicer/cleaner.

How did you verify that the define is not recognized ? What did "usually" mean in your previous post ?
0
 
LVL 2

Author Closing Comment

by:bachra04
ID: 31507916
yes I'm thinking about putting both client and server in different files
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22762326
You easily can check wether an #if applies by adding a

#error "any text"

after the #if statement

The precompiler would stop at that statement and printout the message.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question