在 OSX 上打开 SDL window 时不要打开终端 window
Don't open terminal window while opening SDL window on OSX
打开SDL程序时,双击图标,也会弹出一个终端window。我们怎样才能避免这种情况?
我在 Windows OS 上看到,有一个编译选项 -mwindows
可以执行此操作,但它不适用于 OSX。
这是我的代码:
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, char *argv[])
{
// SDL window
SDL_Window* window(0);
SDL_Event events;
bool quit(false);
// Initialize SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Initialization error : " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Create window
window = SDL_CreateWindow("Windows", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if(window == 0)
{
std::cout << "Creation error : " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Main loop
while(!quit)
{
SDL_WaitEvent(&events);
if(events.window.event == SDL_WINDOWEVENT_CLOSE)
quit = true;
}
// Quit SDL
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
这是我的 makefile :
# Makefile
.PHONY: clean, mrproper, run
NAME=Program
EXEC=$(NAME)
SRC_DIR=./Sources
HEA_DIR=./Headers
OBJ_DIR=./Objects
SRC=$(wildcard $(SRC_DIR)/*.cpp)
OBJ=$(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRC))
HEA=$(wildcard $(HEA_DIR)/*.h)
FRA_DIR=/Library/Frameworks/SDL2.framework/Headers/
CXX=g++
CXXFLAGS=-W -Wall -std=c++11 -I $(HEA_DIR) \
-I $(FRA_DIR)
LDFLAGS=-F/Library/Frameworks -framework SDL2
all: $(EXEC)
$(EXEC): $(OBJ)
$(CXX) -o $@ $^ $(LDFLAGS)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEA)
$(CXX) -o $@ -c $< $(CXXFLAGS)
clean:
@rm -rf $(OBJ_DIR)/*.o
mrproper: clean
@rm -rf $(EXEC)
run:
@./$(EXEC)
提前致谢
PS : 对不起我的 makefile 的格式我没能改变它!
我不知道是否有 "proper" 方法可以做到这一点,但我将你的程序编译成一个名为 main
的二进制可执行文件:
clang++ main.cpp $(pkg-config --cflags --libs sdl2) -o main
然后我用了here中的appify
,把它变成了常规的"app":
appify main "Mark App"
当我双击闪亮的新 Mark App
时,它会弹出一个 SDL window 而没有终端。
如果您启动 Xcode
并单击 File
->New Project
,它将为您提供创建 "Commandline tool" 或 "Cocoa Application"。我想如果您这样做并创建了两种类型的应用程序,您可以比较并查看生成的文件有何不同并执行此操作,但我自己不了解。
这实际上很容易做到,与 SDL 或您的构建系统无关。
先说一句
完成此任务的正确方法是生成 "app bundle"。关于如何制作一个现有的 questions/documentation 有很多。 @Mark Setchell 在他的回答中介绍了一种这样的方法。
如果出于某种原因您希望避免安装应用程序包,请继续阅读以了解如何做到。
实际发生了什么
当您双击可执行文件或应用程序时,它实际上并没有执行。发生的事情是路径被传递给 Launch Services ,然后它将检查某些东西是 "app bundle" 还是其他东西。如果不是应用程序包,LS 会检查其数据库以查看应使用哪个应用程序打开它。您可以看到(通过在 Finder 中使用 "Get Info")在独立二进制文件的情况下,它被设置为 "Open with" Terminal.app。这就是双击二进制文件时打开终端的原因。
你如何改变行为
您需要让 Launch Services 相信您双击的是一个应用程序包。您唯一需要做的就是将 .app
扩展名添加到您的二进制文件中。就是这样。
我刚刚在 10.13 上测试了这个,在 Xcode 中创建了一个新的 "Command Line Utility"。我只是给它添加了一个 .app
扩展名,然后双击它,它打开了 运行 就好了。我不确定你是否会 运行 遇到使用 stdin
或 stdout
的问题(除了显而易见的)(stderr
似乎被路由到系统控制台)
你甚至可以通过 Xcode(构建设置 -> 打包 -> 在二进制文件中创建 Info.plist 部分)直接将 Info.plist
文件嵌入到二进制文件中,如果你需要一个或只是想要在 Finder 中显示一个版本或其他内容。
限制
但是有一点需要注意,如果涉及代码签名,您不能直接拆开现有的应用程序包来尝试。从链接到框架的现有包中提取的二进制文件的 @rpath
需要更改。同上任何捆绑资源。
如前所述,您确实没有 stdin
或 stdout
。 SDL 应用程序可能并不关心,因为它会创建自己的 UI;除了也许应该在控制台定向的日志记录。
打开SDL程序时,双击图标,也会弹出一个终端window。我们怎样才能避免这种情况?
我在 Windows OS 上看到,有一个编译选项 -mwindows
可以执行此操作,但它不适用于 OSX。
这是我的代码:
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, char *argv[])
{
// SDL window
SDL_Window* window(0);
SDL_Event events;
bool quit(false);
// Initialize SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Initialization error : " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Create window
window = SDL_CreateWindow("Windows", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if(window == 0)
{
std::cout << "Creation error : " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Main loop
while(!quit)
{
SDL_WaitEvent(&events);
if(events.window.event == SDL_WINDOWEVENT_CLOSE)
quit = true;
}
// Quit SDL
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
这是我的 makefile :
# Makefile
.PHONY: clean, mrproper, run
NAME=Program
EXEC=$(NAME)
SRC_DIR=./Sources
HEA_DIR=./Headers
OBJ_DIR=./Objects
SRC=$(wildcard $(SRC_DIR)/*.cpp)
OBJ=$(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRC))
HEA=$(wildcard $(HEA_DIR)/*.h)
FRA_DIR=/Library/Frameworks/SDL2.framework/Headers/
CXX=g++
CXXFLAGS=-W -Wall -std=c++11 -I $(HEA_DIR) \
-I $(FRA_DIR)
LDFLAGS=-F/Library/Frameworks -framework SDL2
all: $(EXEC)
$(EXEC): $(OBJ)
$(CXX) -o $@ $^ $(LDFLAGS)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEA)
$(CXX) -o $@ -c $< $(CXXFLAGS)
clean:
@rm -rf $(OBJ_DIR)/*.o
mrproper: clean
@rm -rf $(EXEC)
run:
@./$(EXEC)
提前致谢
PS : 对不起我的 makefile 的格式我没能改变它!
我不知道是否有 "proper" 方法可以做到这一点,但我将你的程序编译成一个名为 main
的二进制可执行文件:
clang++ main.cpp $(pkg-config --cflags --libs sdl2) -o main
然后我用了here中的appify
,把它变成了常规的"app":
appify main "Mark App"
当我双击闪亮的新 Mark App
时,它会弹出一个 SDL window 而没有终端。
如果您启动 Xcode
并单击 File
->New Project
,它将为您提供创建 "Commandline tool" 或 "Cocoa Application"。我想如果您这样做并创建了两种类型的应用程序,您可以比较并查看生成的文件有何不同并执行此操作,但我自己不了解。
这实际上很容易做到,与 SDL 或您的构建系统无关。
先说一句
完成此任务的正确方法是生成 "app bundle"。关于如何制作一个现有的 questions/documentation 有很多。 @Mark Setchell 在他的回答中介绍了一种这样的方法。
如果出于某种原因您希望避免安装应用程序包,请继续阅读以了解如何做到。
实际发生了什么
当您双击可执行文件或应用程序时,它实际上并没有执行。发生的事情是路径被传递给 Launch Services ,然后它将检查某些东西是 "app bundle" 还是其他东西。如果不是应用程序包,LS 会检查其数据库以查看应使用哪个应用程序打开它。您可以看到(通过在 Finder 中使用 "Get Info")在独立二进制文件的情况下,它被设置为 "Open with" Terminal.app。这就是双击二进制文件时打开终端的原因。
你如何改变行为
您需要让 Launch Services 相信您双击的是一个应用程序包。您唯一需要做的就是将 .app
扩展名添加到您的二进制文件中。就是这样。
我刚刚在 10.13 上测试了这个,在 Xcode 中创建了一个新的 "Command Line Utility"。我只是给它添加了一个 .app
扩展名,然后双击它,它打开了 运行 就好了。我不确定你是否会 运行 遇到使用 stdin
或 stdout
的问题(除了显而易见的)(stderr
似乎被路由到系统控制台)
你甚至可以通过 Xcode(构建设置 -> 打包 -> 在二进制文件中创建 Info.plist 部分)直接将 Info.plist
文件嵌入到二进制文件中,如果你需要一个或只是想要在 Finder 中显示一个版本或其他内容。
限制
但是有一点需要注意,如果涉及代码签名,您不能直接拆开现有的应用程序包来尝试。从链接到框架的现有包中提取的二进制文件的 @rpath
需要更改。同上任何捆绑资源。
如前所述,您确实没有 stdin
或 stdout
。 SDL 应用程序可能并不关心,因为它会创建自己的 UI;除了也许应该在控制台定向的日志记录。